Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions apps/web/app/(all)/settings/profile/[profileTabId]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand All @@ -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";

Expand All @@ -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 <Navigate to="/settings/profile/general" replace />;
}

if (!currentUser || !isAValidTab)
return (
<div className="grid size-full place-items-center px-4">
Expand Down
5 changes: 3 additions & 2 deletions apps/web/core/components/onboarding/profile-setup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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";

Expand Down Expand Up @@ -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;

Expand Down
6 changes: 3 additions & 3 deletions apps/web/core/components/onboarding/steps/profile/root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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();
Expand Down Expand Up @@ -190,7 +193,9 @@ export const GeneralProfileSettingsForm = observer(function GeneralProfileSettin

return (
<>
<DeactivateAccountModal isOpen={deactivateAccountModal} onClose={() => setDeactivateAccountModal(false)} />
{!hideDeactivateAccount && (
<DeactivateAccountModal isOpen={deactivateAccountModal} onClose={() => setDeactivateAccountModal(false)} />
)}
<ChangeEmailModal isOpen={isChangeEmailModalOpen} onClose={() => setIsChangeEmailModalOpen(false)} />
<Controller
control={control}
Expand Down Expand Up @@ -400,17 +405,19 @@ export const GeneralProfileSettingsForm = observer(function GeneralProfileSettin
</div>
</div>
</form>
<div className="mt-10">
<SettingsBoxedControlItem
title={t("deactivate_account")}
description={t("deactivate_account_description")}
control={
<Button variant="error-outline" onClick={() => setDeactivateAccountModal(true)}>
{t("deactivate_account")}
</Button>
}
/>
</div>
{!hideDeactivateAccount && (
<div className="mt-10">
<SettingsBoxedControlItem
title={t("deactivate_account")}
description={t("deactivate_account_description")}
control={
<Button variant="error-outline" onClick={() => setDeactivateAccountModal(true)}>
{t("deactivate_account")}
</Button>
}
/>
</div>
)}
</>
);
});
5 changes: 4 additions & 1 deletion apps/web/core/components/settings/profile/modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand All @@ -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({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand All @@ -40,11 +42,14 @@ export const ProfileSettingsSidebarItemCategories = observer(function ProfileSet
const { profileTabId } = useParams();
// translation
const { t } = useTranslation();
const hideSecurityTab = isSsoAuth();

return (
<div className="mt-4 flex flex-col gap-y-4">
{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;

Expand Down
9 changes: 9 additions & 0 deletions apps/web/helpers/auth-config.helper.ts
Original file line number Diff line number Diff line change
@@ -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";
8 changes: 8 additions & 0 deletions apps/web/vite-process-env.d.ts
Original file line number Diff line number Diff line change
@@ -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<string, string | undefined>;
};
}