From 44a4580afac1db6128998c44dc525fdcb0b7bc06 Mon Sep 17 00:00:00 2001 From: jakub-tldr <78603704+jakub-tldr@users.noreply.github.com> Date: Wed, 25 Feb 2026 14:02:32 +0100 Subject: [PATCH 01/15] disable external mfa when there are no business license --- .../AddLocationPage/steps/AddLocationMfaStep.tsx | 15 ++++++++++++++- web/src/shared/defguard-ui | 2 +- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/web/src/pages/AddLocationPage/steps/AddLocationMfaStep.tsx b/web/src/pages/AddLocationPage/steps/AddLocationMfaStep.tsx index 24907b56fe..89df7d1e24 100644 --- a/web/src/pages/AddLocationPage/steps/AddLocationMfaStep.tsx +++ b/web/src/pages/AddLocationPage/steps/AddLocationMfaStep.tsx @@ -1,7 +1,9 @@ -import { useEffect, useState } from 'react'; +import { useQuery } from '@tanstack/react-query'; +import { useEffect, useMemo, useState } from 'react'; import z from 'zod'; import { m } from '../../../paraglide/messages'; import { LocationMfaMode, type NetworkLocation } from '../../../shared/api/types'; +import { businessBadgeProps } from '../../../shared/components/badges/BusinessBadge'; import { WizardCard } from '../../../shared/components/wizard/WizardCard/WizardCard'; import { Button } from '../../../shared/defguard-ui/components/Button/Button'; import { Input } from '../../../shared/defguard-ui/components/Input/Input'; @@ -10,6 +12,8 @@ import { Radio } from '../../../shared/defguard-ui/components/Radio/Radio'; import { SizedBox } from '../../../shared/defguard-ui/components/SizedBox/SizedBox'; import { ThemeSpacing } from '../../../shared/defguard-ui/types'; import { isPresent } from '../../../shared/defguard-ui/utils/isPresent'; +import { getLicenseInfoQueryOptions } from '../../../shared/query'; +import { canUseBusinessFeature } from '../../../shared/utils/license'; import { AddLocationPageStep } from '../types'; import { useAddLocationStore } from '../useAddLocationStore'; @@ -20,6 +24,11 @@ const schema = z export const AddLocationMfaStep = () => { const [error, setError] = useState(null); const [disconnect, setDisconnect] = useState(300); + const { data: licenseInfo } = useQuery(getLicenseInfoQueryOptions); + const canUseFeature = useMemo(() => { + if (licenseInfo === undefined) return undefined; + return canUseBusinessFeature(licenseInfo).result; + }, [licenseInfo]); const [choice, setChoice] = useState( LocationMfaMode.Disabled, @@ -67,7 +76,11 @@ export const AddLocationMfaStep = () => { active={choice === LocationMfaMode.External} onClick={() => setChoice(LocationMfaMode.External)} text="External MFA" + disabled={isPresent(canUseFeature) && !canUseFeature} testId="enforce-external-mfa" + badgeProps={ + isPresent(canUseFeature) && !canUseFeature ? businessBadgeProps : undefined + } /> {choice !== LocationMfaMode.Disabled && ( <> diff --git a/web/src/shared/defguard-ui b/web/src/shared/defguard-ui index 49862aabd9..9a6f90c697 160000 --- a/web/src/shared/defguard-ui +++ b/web/src/shared/defguard-ui @@ -1 +1 @@ -Subproject commit 49862aabd9b8b2d3e675a50ff56b4e3a544cd254 +Subproject commit 9a6f90c697503560ff6e7002b7c2f722babd777b From 8027aa7deca655f7dd7e8127ce30e1acf379a46c Mon Sep 17 00:00:00 2001 From: jakub-tldr <78603704+jakub-tldr@users.noreply.github.com> Date: Wed, 25 Feb 2026 14:17:08 +0100 Subject: [PATCH 02/15] block firewall in wizard without business license --- web/messages/en/location.json | 1 + .../assets/business-feature-icon.png | Bin 0 -> 20535 bytes .../steps/AddLocationFirewallStep.tsx | 41 +++++++++++++++++- 3 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 web/src/pages/AddLocationPage/assets/business-feature-icon.png diff --git a/web/messages/en/location.json b/web/messages/en/location.json index 7b7bd2fd01..afdc64d6f1 100644 --- a/web/messages/en/location.json +++ b/web/messages/en/location.json @@ -1,5 +1,6 @@ { "$schema": "https://inlang.com/schema/inlang-message-format", + "add_location_firewall_no_license_subtitle": "Firewall is available only in Business and Enterprise plans. You can still create location now and activate Firewall later by upgrading your plan.", "location_delete_success": "Location deleted", "location_delete_failed": "Failed to delete location", "location_edit_failed": "Failed to update location", diff --git a/web/src/pages/AddLocationPage/assets/business-feature-icon.png b/web/src/pages/AddLocationPage/assets/business-feature-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..bbd9ef43378ee13d7b2d950f65990e8f6acf57db GIT binary patch literal 20535 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 KMNUMnLSTZ&a+~!4 literal 0 HcmV?d00001 diff --git a/web/src/pages/AddLocationPage/steps/AddLocationFirewallStep.tsx b/web/src/pages/AddLocationPage/steps/AddLocationFirewallStep.tsx index 39323ad6c9..cb1c77817b 100644 --- a/web/src/pages/AddLocationPage/steps/AddLocationFirewallStep.tsx +++ b/web/src/pages/AddLocationPage/steps/AddLocationFirewallStep.tsx @@ -1,7 +1,7 @@ -import { useMutation } from '@tanstack/react-query'; +import { useMutation, useQuery } from '@tanstack/react-query'; import { useNavigate } from '@tanstack/react-router'; import { cloneDeep, omit } from 'lodash-es'; -import { useCallback, useState } from 'react'; +import { useCallback, useMemo, useState } from 'react'; import { m } from '../../../paraglide/messages'; import api from '../../../shared/api/api'; import { ActionCard } from '../../../shared/components/ActionCard/ActionCard'; @@ -13,8 +13,13 @@ import { ModalControls } from '../../../shared/defguard-ui/components/ModalContr import { Radio } from '../../../shared/defguard-ui/components/Radio/Radio'; import { SizedBox } from '../../../shared/defguard-ui/components/SizedBox/SizedBox'; import { ThemeSpacing } from '../../../shared/defguard-ui/types'; +import { isPresent } from '../../../shared/defguard-ui/utils/isPresent'; +import { externalLink } from '../../../shared/constants'; +import { getLicenseInfoQueryOptions } from '../../../shared/query'; +import { canUseBusinessFeature } from '../../../shared/utils/license'; import { useGatewayWizardStore } from '../../GatewaySetupPage/useGatewayWizardStore'; import actionCardImage from '../assets/gateway-setup-action-card.png'; +import businessFeatureCardImage from '../assets/business-feature-icon.png'; import { AddLocationPageStep } from '../types'; import { useAddLocationStore } from '../useAddLocationStore'; @@ -25,6 +30,13 @@ export const AddLocationFirewallStep = () => { const [state, setState] = useState('disable'); const navigate = useNavigate(); + const { data: licenseInfo } = useQuery(getLicenseInfoQueryOptions); + const canUseFeature = useMemo(() => { + if (licenseInfo === undefined) return undefined; + return canUseBusinessFeature(licenseInfo).result; + }, [licenseInfo]); + const firewallLocked = isPresent(canUseFeature) && !canUseFeature; + const { mutate, isPending } = useMutation({ mutationFn: api.location.addLocation, meta: { @@ -75,12 +87,35 @@ export const AddLocationFirewallStep = () => { return ( + {firewallLocked && ( + <> + + +