diff --git a/apps/web/app/(all)/settings/profile/[profileTabId]/page.tsx b/apps/web/app/(all)/settings/profile/[profileTabId]/page.tsx
index d7df27ccbcd..9ece9e80b28 100644
--- a/apps/web/app/(all)/settings/profile/[profileTabId]/page.tsx
+++ b/apps/web/app/(all)/settings/profile/[profileTabId]/page.tsx
@@ -5,6 +5,7 @@
*/
import { observer } from "mobx-react";
+import { Navigate } from "react-router";
// plane imports
import { PROFILE_SETTINGS_TABS } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
@@ -17,6 +18,8 @@ import { ProfileSettingsSidebarRoot } from "@/components/settings/profile/sideba
// hooks
import { useUser } from "@/hooks/store/user";
import { useAppRouter } from "@/hooks/use-app-router";
+// helpers
+import { isSsoAuth } from "@/helpers/auth-config.helper";
// local imports
import type { Route } from "../+types/layout";
@@ -31,6 +34,10 @@ function ProfileSettingsPage(props: Route.ComponentProps) {
// derived values
const isAValidTab = PROFILE_SETTINGS_TABS.includes(profileTabId as TProfileSettingsTabs);
+ if (isSsoAuth() && profileTabId === "security") {
+ return ;
+ }
+
if (!currentUser || !isAValidTab)
return (
diff --git a/apps/web/core/components/onboarding/profile-setup.tsx b/apps/web/core/components/onboarding/profile-setup.tsx
index c466e1f0478..d0cf8842e1e 100644
--- a/apps/web/core/components/onboarding/profile-setup.tsx
+++ b/apps/web/core/components/onboarding/profile-setup.tsx
@@ -21,6 +21,8 @@ import { cn, getFileURL, getPasswordStrength, validatePersonName } from "@plane/
import { UserImageUploadModal } from "@/components/core/modals/user-image-upload-modal";
// hooks
import { useUser, useUserProfile } from "@/hooks/store/user";
+// helpers
+import { isSsoAuth } from "@/helpers/auth-config.helper";
// services
import { AuthService } from "@/services/auth.service";
@@ -220,8 +222,7 @@ export const ProfileSetup = observer(function ProfileSetup(props: Props) {
// derived values
const isPasswordAlreadySetup = !user?.is_password_autoset;
- const isSsoAuth = (import.meta.env.VITE_AUTH_TYPE?.toString() ?? "").trim().toUpperCase() === "SSO";
- const showOptionalPassword = !isSsoAuth && !isPasswordAlreadySetup;
+ const showOptionalPassword = !isSsoAuth() && !isPasswordAlreadySetup;
const currentPassword = watch("password") || undefined;
const currentConfirmPassword = watch("confirm_password") || undefined;
diff --git a/apps/web/core/components/onboarding/steps/profile/root.tsx b/apps/web/core/components/onboarding/steps/profile/root.tsx
index bde25779a68..90b53325308 100644
--- a/apps/web/core/components/onboarding/steps/profile/root.tsx
+++ b/apps/web/core/components/onboarding/steps/profile/root.tsx
@@ -20,6 +20,8 @@ import { UserImageUploadModal } from "@/components/core/modals/user-image-upload
// hooks
import { useInstance } from "@/hooks/store/use-instance";
import { useUser, useUserProfile } from "@/hooks/store/user";
+// helpers
+import { isSsoAuth } from "@/helpers/auth-config.helper";
// services
import { AuthService } from "@/services/auth.service";
// local components
@@ -121,9 +123,7 @@ export const ProfileSetupStep = observer(function ProfileSetupStep({ handleStepC
// derived values
const isPasswordAlreadySetup = !user?.is_password_autoset;
- // Hide optional password on SSO builds only (VITE_AUTH_TYPE baked at build time).
- const isSsoAuth = (import.meta.env.VITE_AUTH_TYPE ?? "").trim().toUpperCase() === "SSO";
- const showOptionalPassword = !isSsoAuth && !isPasswordAlreadySetup;
+ const showOptionalPassword = !isSsoAuth() && !isPasswordAlreadySetup;
const currentPassword = watch("password") || undefined;
const currentConfirmPassword = watch("confirm_password") || undefined;
diff --git a/apps/web/core/components/settings/profile/content/pages/general/form.tsx b/apps/web/core/components/settings/profile/content/pages/general/form.tsx
index e20245f8352..71075e63c66 100644
--- a/apps/web/core/components/settings/profile/content/pages/general/form.tsx
+++ b/apps/web/core/components/settings/profile/content/pages/general/form.tsx
@@ -30,6 +30,8 @@ import { useInstance } from "@/hooks/store/use-instance";
import { useUser, useUserProfile } from "@/hooks/store/user";
// utils
import { validatePersonName, validateDisplayName } from "@plane/utils";
+// helpers
+import { isSsoAuth } from "@/helpers/auth-config.helper";
type TUserProfileForm = {
avatar_url: string;
@@ -56,6 +58,7 @@ export const GeneralProfileSettingsForm = observer(function GeneralProfileSettin
const [isLoading, setIsLoading] = useState(false);
const [isImageUploadModalOpen, setIsImageUploadModalOpen] = useState(false);
const [deactivateAccountModal, setDeactivateAccountModal] = useState(false);
+ const hideDeactivateAccount = isSsoAuth();
const [isChangeEmailModalOpen, setIsChangeEmailModalOpen] = useState(false);
// language support
const { t } = useTranslation();
@@ -190,7 +193,9 @@ export const GeneralProfileSettingsForm = observer(function GeneralProfileSettin
return (
<>
- setDeactivateAccountModal(false)} />
+ {!hideDeactivateAccount && (
+ setDeactivateAccountModal(false)} />
+ )}
setIsChangeEmailModalOpen(false)} />
-
- setDeactivateAccountModal(true)}>
- {t("deactivate_account")}
-
- }
- />
-
+ {!hideDeactivateAccount && (
+
+ setDeactivateAccountModal(true)}>
+ {t("deactivate_account")}
+
+ }
+ />
+
+ )}
>
);
});
diff --git a/apps/web/core/components/settings/profile/modal.tsx b/apps/web/core/components/settings/profile/modal.tsx
index 43abd90afbf..99a88038d33 100644
--- a/apps/web/core/components/settings/profile/modal.tsx
+++ b/apps/web/core/components/settings/profile/modal.tsx
@@ -12,6 +12,8 @@ import { IconButton } from "@plane/propel/icon-button";
import { EModalPosition, EModalWidth, ModalCore } from "@plane/ui";
// hooks
import { useCommandPalette } from "@/hooks/store/use-command-palette";
+// helpers
+import { isSsoAuth } from "@/helpers/auth-config.helper";
// local imports
import { ProfileSettingsContent } from "./content";
import { ProfileSettingsSidebarRoot } from "./sidebar";
@@ -20,7 +22,8 @@ export const ProfileSettingsModal = observer(function ProfileSettingsModal() {
// store hooks
const { profileSettingsModal, toggleProfileSettingsModal } = useCommandPalette();
// derived values
- const activeTab = profileSettingsModal.activeTab ?? "general";
+ const requestedTab = profileSettingsModal.activeTab ?? "general";
+ const activeTab = isSsoAuth() && requestedTab === "security" ? "general" : requestedTab;
const handleClose = useCallback(() => {
toggleProfileSettingsModal({
diff --git a/apps/web/core/components/settings/profile/sidebar/item-categories.tsx b/apps/web/core/components/settings/profile/sidebar/item-categories.tsx
index d1ee973f3ee..b4e9f4c13c1 100644
--- a/apps/web/core/components/settings/profile/sidebar/item-categories.tsx
+++ b/apps/web/core/components/settings/profile/sidebar/item-categories.tsx
@@ -14,6 +14,8 @@ import { GROUPED_PROFILE_SETTINGS, PROFILE_SETTINGS_CATEGORIES } from "@plane/co
import { useTranslation } from "@plane/i18n";
import type { ISvgIcons } from "@plane/propel/icons";
import type { TProfileSettingsTabs } from "@plane/types";
+// helpers
+import { isSsoAuth } from "@/helpers/auth-config.helper";
// local imports
import { SettingsSidebarItem } from "../../sidebar/item";
import { ProfileSettingsSidebarWorkspaceOptions } from "./workspace-options";
@@ -40,11 +42,14 @@ export const ProfileSettingsSidebarItemCategories = observer(function ProfileSet
const { profileTabId } = useParams();
// translation
const { t } = useTranslation();
+ const hideSecurityTab = isSsoAuth();
return (
{PROFILE_SETTINGS_CATEGORIES.map((category) => {
- const categoryItems = GROUPED_PROFILE_SETTINGS[category];
+ const categoryItems = GROUPED_PROFILE_SETTINGS[category].filter(
+ (item) => !(hideSecurityTab && item.key === "security")
+ );
if (categoryItems.length === 0) return null;
diff --git a/apps/web/helpers/auth-config.helper.ts b/apps/web/helpers/auth-config.helper.ts
new file mode 100644
index 00000000000..1ada1eb8ba8
--- /dev/null
+++ b/apps/web/helpers/auth-config.helper.ts
@@ -0,0 +1,9 @@
+/**
+ * Copyright (c) 2023-present Plane Software, Inc. and contributors
+ * SPDX-License-Identifier: AGPL-3.0-only
+ * See the LICENSE file for details.
+ */
+
+/** True when the web build is configured for SSO auth (VITE_AUTH_TYPE=SSO). */
+export const isSsoAuth = (): boolean =>
+ (import.meta.env.VITE_AUTH_TYPE?.toString() ?? "").trim().toUpperCase() === "SSO";
diff --git a/apps/web/vite-process-env.d.ts b/apps/web/vite-process-env.d.ts
new file mode 100644
index 00000000000..1889ad76191
--- /dev/null
+++ b/apps/web/vite-process-env.d.ts
@@ -0,0 +1,8 @@
+// `process.env` is replaced at build time in apps/web/vite.config.ts (`define`).
+export {};
+
+declare global {
+ const process: {
+ env: Record;
+ };
+}