diff --git a/.changeset/seven-games-sell.md b/.changeset/seven-games-sell.md new file mode 100644 index 00000000000..e2e4d34106e --- /dev/null +++ b/.changeset/seven-games-sell.md @@ -0,0 +1,11 @@ +--- +"@wso2is/admin.application-templates.v1": patch +"@wso2is/admin.server-configurations.v1": patch +"@wso2is/admin.feature-gate.v1": patch +"@wso2is/admin.branding.v1": patch +"@wso2is/admin.actions.v1": patch +"@wso2is/console": patch +"@wso2is/core": patch +--- + +Introduce configuration based feature status flag support diff --git a/apps/console/java/org.wso2.identity.apps.console.server.feature/resources/deployment.config.json.j2 b/apps/console/java/org.wso2.identity.apps.console.server.feature/resources/deployment.config.json.j2 index b6c40678d6f..2e23363bd48 100644 --- a/apps/console/java/org.wso2.identity.apps.console.server.feature/resources/deployment.config.json.j2 +++ b/apps/console/java/org.wso2.identity.apps.console.server.feature/resources/deployment.config.json.j2 @@ -222,6 +222,13 @@ {% endif %} ], "enabled": {{ feature.enabled }}, + "featureFlags": { + {% if feature.feature_flags is defined %} + {% for flag, value in feature.feature_flags.items() %} + "{{ flag }}": {{ value }}{{ "," if not loop.last }} + {% endfor %} + {% endif %} + }, "scopes": { {% if feature.scopes is defined %} {% for operation, scopes in feature.scopes.items() %} diff --git a/apps/console/src/configs/routes.tsx b/apps/console/src/configs/routes.tsx index 0edf022e722..6080b351482 100644 --- a/apps/console/src/configs/routes.tsx +++ b/apps/console/src/configs/routes.tsx @@ -1,5 +1,5 @@ /** - * Copyright (c) 2023-2024, WSO2 LLC. (https://www.wso2.com). + * Copyright (c) 2023-2025, WSO2 LLC. (https://www.wso2.com). * * WSO2 LLC. licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except @@ -34,8 +34,8 @@ import { import { getSidePanelIcons } from "@wso2is/admin.core.v1/configs/ui"; import { AppConstants } from "@wso2is/admin.core.v1/constants"; import { commonConfig } from "@wso2is/admin.extensions.v1"; +import FeatureFlagConstants from "@wso2is/admin.feature-gate.v1/constants/feature-flag-constants"; import FeatureGateConstants from "@wso2is/admin.feature-gate.v1/constants/feature-gate-constants"; -import { FeatureStatusLabel } from "@wso2is/admin.feature-gate.v1/models/feature-status"; import { ServerConfigurationsConstants } from "@wso2is/admin.server-configurations.v1"; import { LegacyModeInterface, RouteInterface } from "@wso2is/core/models"; import compact from "lodash-es/compact"; @@ -71,8 +71,6 @@ import FullScreenLayout from "../layouts/full-screen-layout"; export const getAppViewRoutes = (): RouteInterface[] => { const legacyMode: LegacyModeInterface = window["AppUtils"]?.getConfig()?.ui?.legacyMode; - const showStatusLabelForNewAuthzRuntimeFeatures: boolean = - window["AppUtils"]?.getConfig()?.ui?.showStatusLabelForNewAuthzRuntimeFeatures; const defaultRoutes: RouteInterface[] = [ { @@ -719,8 +717,7 @@ export const getAppViewRoutes = (): RouteInterface[] => { import("@wso2is/admin.sms-templates.v1/pages/sms-customization") ), exact: true, - featureStatus: "NEW", - featureStatusLabel: FeatureStatusLabel.NEW, + featureFlagKey: FeatureFlagConstants.FEATURE_FLAG_KEY_MAP.SMS_TEMPLATES, icon: { icon: getSidePanelIcons().sms }, @@ -1049,9 +1046,8 @@ export const getAppViewRoutes = (): RouteInterface[] => { category: "extensions:develop.sidePanel.categories.monitor", component: lazy(() => import("@wso2is/admin.org-insights.v1/pages/org-insights")), exact: true, + featureFlagKey: FeatureFlagConstants.FEATURE_FLAG_KEY_MAP.INSIGHTS, featureGateIds: [ FeatureGateConstants.SAAS_FEATURES_IDENTIFIER ], - featureStatus: "BETA", - featureStatusLabel: "common:beta", icon: { icon: }, @@ -1239,8 +1235,7 @@ export const getAppViewRoutes = (): RouteInterface[] => { ], component: lazy(() => import("@wso2is/admin.roles.v2/pages/role")), exact: true, - featureStatus: showStatusLabelForNewAuthzRuntimeFeatures ? "NEW" : "", - featureStatusLabel: showStatusLabelForNewAuthzRuntimeFeatures ? "common:new": "", + featureFlagKey: FeatureFlagConstants.FEATURE_FLAG_KEY_MAP.USER_ROLES, icon: { icon: getSidePanelIcons().applicationRoles }, @@ -1300,8 +1295,7 @@ export const getAppViewRoutes = (): RouteInterface[] => { import("@wso2is/admin.actions.v1/pages/actions") ), exact: true, - featureStatus: "BETA", - featureStatusLabel: FeatureStatusLabel.BETA, + featureFlagKey: FeatureFlagConstants.FEATURE_FLAG_KEY_MAP.ACTIONS, icon: { icon: }, diff --git a/apps/console/src/layouts/dashboard-layout.tsx b/apps/console/src/layouts/dashboard-layout.tsx index af3cda27242..4ed9d379a9a 100644 --- a/apps/console/src/layouts/dashboard-layout.tsx +++ b/apps/console/src/layouts/dashboard-layout.tsx @@ -1,5 +1,5 @@ /** - * Copyright (c) 2023, WSO2 LLC. (https://www.wso2.com). + * Copyright (c) 2023-2025, WSO2 LLC. (https://www.wso2.com). * * WSO2 LLC. licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except @@ -27,6 +27,7 @@ import { AppState, AppUtils, ConfigReducerStateInterface, + FeatureConfigInterface, ProtectedRoute, RouteUtils, UIConstants, @@ -37,15 +38,18 @@ import Header from "@wso2is/admin.core.v1/components/header"; import { CommonUtils as ConsoleCommonUtils } from "@wso2is/admin.core.v1/utils"; import { applicationConfig } from "@wso2is/admin.extensions.v1"; import FeatureGateConstants from "@wso2is/admin.feature-gate.v1/constants/feature-gate-constants"; +import { FeatureStatusLabel } from "@wso2is/admin.feature-gate.v1/models/feature-status"; import { AlertInterface, AnnouncementBannerInterface, + CategorizedRouteInterface, ChildRouteInterface, + FeatureAccessConfigInterface, + FeatureFlagsInterface, NavRouteInterface, ProfileInfoInterface, RouteInterface } from "@wso2is/core/models"; -import { CategorizedRouteInterface } from "@wso2is/core/src/models"; import { initializeAlertSystem } from "@wso2is/core/store"; import { RouteUtils as CommonRouteUtils, CommonUtils } from "@wso2is/core/utils"; import { @@ -138,6 +142,7 @@ const DashboardLayout: FunctionComponent = ( const organizationLoading: boolean = useSelector( (state: AppState) => state?.organization?.getOrganizationLoading ); + const featureConfig: FeatureConfigInterface = useSelector((state: AppState) => state.config.ui.features); const initLoad: MutableRefObject = useRef(true); @@ -296,6 +301,27 @@ const DashboardLayout: FunctionComponent = ( setAnnouncement(validAnnouncement); }; + /** + * Resolves the feature flag status of a given feature. + * + * @param featureName - Name of the feature. + * @param featureKey - Key of the feature. + * + * @returns Feature status label. + */ + const resolveFeatureFlag = (featureName: string, featureKey: string): FeatureStatusLabel=> { + const config: FeatureAccessConfigInterface = featureConfig?.[featureName]; + + if (!config) { + return null; + } + + const featureFlag: FeatureFlagsInterface = config?.featureFlags?.find( + (featureFlag: FeatureFlagsInterface) => featureFlag.feature === featureKey); + + return FeatureStatusLabel[featureFlag?.flag]; + }; + const generateNavbarItems = (): NavbarItems[] => { const categorizedRoutes: CategorizedRouteInterface = {}; @@ -320,34 +346,42 @@ const DashboardLayout: FunctionComponent = ( return Object.entries(categorizedRoutes).map( ([ _navCategory, routes ]: [ navCategory: string, routes: NavRouteInterface[] ]) => { - return { - items: routes.map((route: NavRouteInterface) => ({ - "data-componentid": `side-panel-items-${ kebabCase(route.id) }`, - "data-testid": `side-panel-items-${ kebabCase(route.id) }`, - icon: , - items: route.items?.map((subRoute: NavRouteInterface) => ({ - "data-componentid": `side-panel-items-${ kebabCase(subRoute.id) }`, - "data-testid": `side-panel-items-${ kebabCase(subRoute.id) }`, + items: routes.map((route: NavRouteInterface) => { + const routeFlag: string = resolveFeatureFlag(route.id, route.featureFlagKey); + + return { + "data-componentid": `side-panel-items-${ kebabCase(route.id) }`, + "data-testid": `side-panel-items-${ kebabCase(route.id) }`, icon: , - label: t(subRoute.name), - onClick: () => history.push(subRoute.path), - selected: subRoute.selected ?? selectedRoute?.path === subRoute.path, - tag: t(subRoute.featureStatusLabel) - })), - label: t(route.name), - onClick: () => history.push(route.path), - selected: route.selected ?? isRouteActive(route.path), - tag: t(route.featureStatusLabel) - })) + items: route.items?.map((subRoute: NavRouteInterface) => { + + const subRouteFlag: string = resolveFeatureFlag(subRoute.id, subRoute.featureFlagKey); + + return { + "data-componentid": `side-panel-items-${ kebabCase(subRoute.id) }`, + "data-testid": `side-panel-items-${ kebabCase(subRoute.id) }`, + icon: , + label: t(subRoute.name), + onClick: () => history.push(subRoute.path), + selected: subRoute.selected ?? selectedRoute?.path === subRoute.path, + tag: t(subRouteFlag) + }; + }), + label: t(route.name), + onClick: () => history.push(route.path), + selected: route.selected ?? isRouteActive(route.path), + tag: t(routeFlag) + }; + }) }; } ); diff --git a/apps/console/src/public/deployment.config.json b/apps/console/src/public/deployment.config.json index 548b73a20f0..6d44868e2a4 100644 --- a/apps/console/src/public/deployment.config.json +++ b/apps/console/src/public/deployment.config.json @@ -213,6 +213,7 @@ "accountLogin": { "disabledFeatures": [], "enabled": true, + "featureFlags": [], "scopes": { "update": [ "internal_config_mgt_update" @@ -222,6 +223,7 @@ "accountRecovery": { "disabledFeatures": [], "enabled": true, + "featureFlags": [], "scopes": { "create": [], "delete": [], @@ -239,6 +241,7 @@ "accountSecurity": { "disabledFeatures": [], "enabled": true, + "featureFlags": [], "scopes": { "create": [], "delete": [], @@ -254,8 +257,33 @@ } }, "actions": { - "disabledFeatures": [], + "disabledFeatures": [ + "actions.filterPreRegistration", + "actions.filterPreUpdateProfile" + ], "enabled": true, + "featureFlags": [ + { + "feature": "actions", + "flag": "" + }, + { + "feature": "actions.create.types.list.preIssueAccessToken", + "flag": "" + }, + { + "feature": "actions.create.types.list.preUpdatePassword", + "flag": "" + }, + { + "feature": "actions.create.types.list.preUpdateProfile", + "flag": "" + }, + { + "feature": "actions.create.types.list.preRegistration", + "flag": "" + } + ], "scopes": { "create": [ "internal_action_mgt_create" @@ -277,11 +305,13 @@ "adminAdvisoryBanner": { "disabledFeatures": [], "enabled": true, + "featureFlags": [], "scopes": {} }, "administrators": { "disabledFeatures": [], "enabled": false, + "featureFlags": [], "scopes": { "create": [], "delete": [], @@ -292,6 +322,7 @@ "ai": { "disabledFeatures": [], "enabled": false, + "featureFlags": [], "scopes": { "create": [], "delete": [], @@ -303,6 +334,7 @@ "analytics": { "disabledFeatures": [], "enabled": true, + "featureFlags": [], "scopes": { "create": [], "delete": [], @@ -320,6 +352,7 @@ "apiResources": { "disabledFeatures": [], "enabled": true, + "featureFlags": [], "scopes": { "create": [ "internal_api_resource_create" @@ -341,6 +374,7 @@ "applicationRoles": { "disabledFeatures": [], "enabled": false, + "featureFlags": [], "scopes": { "create": [], "delete": [], @@ -353,6 +387,20 @@ "applications.loginFlow.legacyEditor" ], "enabled": true, + "featureFlags": [ + { + "feature": "applications", + "flag": "" + }, + { + "feature": "applications.templates", + "flag": "" + }, + { + "feature": "applications.edit.general.branding", + "flag": "" + } + ], "scopes": { "create": [ "internal_application_mgt_create" @@ -378,6 +426,7 @@ "approvals": { "disabledFeatures": [], "enabled": false, + "featureFlags": [], "scopes": { "create": [ "internal_humantask_view" @@ -399,6 +448,7 @@ "attributeDialects": { "disabledFeatures": [], "enabled": true, + "featureFlags": [], "scopes": { "create": [ "internal_claim_meta_create" @@ -421,6 +471,7 @@ "auditLogs": { "disabledFeatures": [], "enabled": true, + "featureFlags": [], "scopes": { "update": [ "internal_application_mgt_view" @@ -432,6 +483,32 @@ "branding.hostnameUrlBranding" ], "enabled": true, + "featureFlags": [ + { + "feature": "branding", + "flag": "" + }, + { + "feature": "branding.stylesAndText", + "flag": "" + }, + { + "feature": "branding.emailTemplates", + "flag": "" + }, + { + "feature": "branding.stylesAndText.application.title", + "flag": "" + }, + { + "feature": "branding.stylesAndText.application.text", + "flag": "" + }, + { + "feature": "branding.stylesAndText.organization.text", + "flag": "" + } + ], "scopes": { "create": [ "internal_branding_preference_update" @@ -453,6 +530,7 @@ "bulkUserImport": { "disabledFeatures": [], "enabled": true, + "featureFlags": [], "fileImportTimeout": 90000, "scopes": { "create": [ @@ -473,6 +551,7 @@ "certificates": { "disabledFeatures": [], "enabled": false, + "featureFlags": [], "scopes": { "create": [ "internal_keystore_update" @@ -497,6 +576,7 @@ "consoleSettings.privilegedUsers" ], "enabled": true, + "featureFlags": [], "scopes": { "create": [ "internal_role_mgt_create" @@ -525,6 +605,7 @@ "emailProviders": { "disabledFeatures": [], "enabled": true, + "featureFlags": [], "scopes": { "create": [ "internal_notification_senders_create" @@ -543,6 +624,7 @@ "emailTemplates": { "disabledFeatures": [], "enabled": true, + "featureFlags": [], "scopes": { "create": [ "internal_email_mgt_create" @@ -564,6 +646,7 @@ "eventPublishing": { "disabledFeatures": [], "enabled": true, + "featureFlags": [], "scopes": { "create": [ "internal_event_config_update" @@ -625,6 +708,7 @@ "groups": { "disabledFeatures": [], "enabled": true, + "featureFlags": [], "scopes": { "create": [ "internal_group_mgt_create" @@ -650,6 +734,7 @@ "guestUser": { "disabledFeatures": [], "enabled": true, + "featureFlags": [], "scopes": { "create": [ "internal_guest_mgt_invite_add" @@ -669,11 +754,13 @@ "identityProviderGroups": { "disabledFeatures": [], "enabled": true, + "featureFlags": [], "scopes": {} }, "identityProviders": { "disabledFeatures": [], "enabled": true, + "featureFlags": [], "scopes": { "create": [ "internal_idp_create" @@ -697,6 +784,7 @@ }, "identityVerificationProviders": { "enabled": true, + "featureFlags": [], "scopes": { "create": [ "internal_idvp_add" @@ -718,11 +806,18 @@ "insights": { "disabledFeatures": [], "enabled": false, + "featureFlags": [ + { + "feature": "insights", + "flag": "" + } + ], "scopes": {} }, "internalNotificationSending": { "disabledFeatures": [], "enabled": true, + "featureFlags": [], "scopes": { "create": [], "delete": [], @@ -740,6 +835,20 @@ "loginAndRegistration": { "disabledFeatures": [], "enabled": true, + "featureFlags": [ + { + "feature": "loginAndRegistration", + "flag": "" + }, + { + "feature": "loginAndRegistration.organizationSettings.discovery", + "flag": "" + }, + { + "feature": "loginAndRegistration.organizationSettings.impersonation", + "flag": "" + } + ], "scopes": { "create": [], "delete": [], @@ -759,6 +868,7 @@ "logs": { "disabledFeatures": [], "enabled": false, + "featureFlags": [], "scopes": { "update": [ "internal_application_mgt_view" @@ -768,6 +878,7 @@ "myAccount": { "disabledFeatures": [], "enabled": false, + "featureFlags": [], "scopes": { "create": [], "delete": [], @@ -778,6 +889,7 @@ "notificationChannels": { "disabledFeatures": [], "enabled": true, + "featureFlags": [], "scopes": { "create": [ "internal_notification_senders_create" @@ -799,6 +911,7 @@ "oidcScopes": { "disabledFeatures": [], "enabled": true, + "featureFlags": [], "scopes": { "create": [ "internal_oidc_scope_mgt_create" @@ -821,6 +934,7 @@ "organizationDiscovery": { "disabledFeatures": [], "enabled": true, + "featureFlags": [], "scopes": { "create": [ "internal_organization_config_add", @@ -847,6 +961,7 @@ "organizations": { "disabledFeatures": [], "enabled": true, + "featureFlags": [], "scopes": { "create": [ "internal_organization_create" @@ -868,6 +983,7 @@ "parentUserInvitation": { "disabledFeatures": [], "enabled": true, + "featureFlags": [], "scopes": { "create": [ "internal_guest_mgt_invite_add" @@ -887,6 +1003,7 @@ "policyAdministration":{ "disabledFeatures": [], "enabled": false, + "featureFlags": [], "scopes": { "create": [], "delete": [], @@ -898,6 +1015,7 @@ "remoteFetchConfig": { "disabledFeatures": [], "enabled": false, + "featureFlags": [], "scopes": { "create": [ "internal_identity_mgt_create", @@ -928,11 +1046,13 @@ "remoteLogging": { "disabledFeatures": [], "enabled": true, + "featureFlags": [], "scopes": {} }, "residentOutboundProvisioning": { "disabledFeatures": [], "enabled": true, + "featureFlags": [], "scopes": { "create": [], "delete": [], @@ -951,6 +1071,7 @@ "ruleBasedPasswordExpiry": { "disabledFeatures": [], "enabled": true, + "featureFlags": [], "scopes": { "create": [], "delete": [], @@ -970,6 +1091,7 @@ "saml2Configuration": { "disabledFeatures": [], "enabled": true, + "featureFlags": [], "scopes": { "create": [], "delete": [], @@ -980,6 +1102,7 @@ "secretsManagement": { "disabledFeatures": [], "enabled": false, + "featureFlags": [], "scopes": { "create": [ "internal_secret_mgt_add" @@ -1001,6 +1124,7 @@ "server": { "disabledFeatures": [], "enabled": true, + "featureFlags": [], "scopes": { "create": [], "delete": [], @@ -1018,6 +1142,7 @@ "sessionManagement": { "disabledFeatures": [], "enabled": true, + "featureFlags": [], "scopes": { "create": [], "delete": [], @@ -1030,6 +1155,7 @@ "choreoAsSMSProvider" ], "enabled": true, + "featureFlags": [], "scopes": { "create": [ "internal_notification_senders_create" @@ -1048,6 +1174,12 @@ "smsTemplates": { "disabledFeatures": [], "enabled": true, + "featureFlags": [ + { + "feature": "smsTemplates", + "flag": "" + } + ], "scopes": { "create": [ "internal_template_mgt_create" @@ -1074,6 +1206,7 @@ "tenants.organizations.quick.nav.from.dropdown" ], "enabled": true, + "featureFlags": [], "scopes": { "create": [ "internal_create_tenants" @@ -1092,6 +1225,7 @@ "tryIt": { "disabledFeatures": [], "enabled": true, + "featureFlags": [], "scopes": { "create": [ "internal_application_mgt_create" @@ -1115,6 +1249,7 @@ "userOnboarding": { "disabledFeatures": [], "enabled": true, + "featureFlags": [], "scopes": { "create": [], "delete": [], @@ -1132,6 +1267,12 @@ "userRoles": { "disabledFeatures": [], "enabled": true, + "featureFlags": [ + { + "feature": "userRoles", + "flag": "" + } + ], "scopes": { "create": [ "internal_role_mgt_create" @@ -1161,6 +1302,7 @@ "userStores.type.remote" ], "enabled": true, + "featureFlags": [], "scopes": { "create": [ "internal_userstore_create" @@ -1182,6 +1324,7 @@ "userV1Roles": { "disabledFeatures": [], "enabled": true, + "featureFlags": [], "scopes": { "create": [ "internal_role_mgt_create" @@ -1208,6 +1351,7 @@ "users": { "disabledFeatures": [], "enabled": true, + "featureFlags": [], "scopes": { "create": [ "internal_user_mgt_create" @@ -1237,6 +1381,7 @@ "wsFedConfiguration": { "disabledFeatures": [], "enabled": true, + "featureFlags": [], "scopes": { "create": [], "delete": [], diff --git a/features/admin.actions.v1/models/actions.ts b/features/admin.actions.v1/models/actions.ts index 5b1313d13ec..16e514952e3 100644 --- a/features/admin.actions.v1/models/actions.ts +++ b/features/admin.actions.v1/models/actions.ts @@ -17,7 +17,6 @@ */ import { HttpMethod } from "@asgardeo/auth-react"; -import { FeatureStatusLabel } from "@wso2is/admin.feature-gate.v1/models/feature-status"; import { RuleWithoutIdInterface } from "@wso2is/admin.rules.v1/models/rules"; import { ReactNode } from "react"; @@ -424,7 +423,7 @@ export interface ActionTypeCardInterface { /** * Feature status label of the Action type. */ - featureStatusLabel: FeatureStatusLabel, + featureStatusKey: string, /** * Heading of the Action type. */ diff --git a/features/admin.actions.v1/pages/actions.tsx b/features/admin.actions.v1/pages/actions.tsx index b95fa255f5f..4fda2fe5b4d 100644 --- a/features/admin.actions.v1/pages/actions.tsx +++ b/features/admin.actions.v1/pages/actions.tsx @@ -29,7 +29,8 @@ import { UserFlowIcon } from "@oxygen-ui/react-icons"; import { AppConstants, AppState, history } from "@wso2is/admin.core.v1"; -import { FeatureStatusLabel } from "@wso2is/admin.feature-gate.v1/models/feature-status"; +import FeatureFlagLabel from "@wso2is/admin.feature-gate.v1/components/feature-flag-label"; +import FeatureFlagConstants from "@wso2is/admin.feature-gate.v1/constants/feature-flag-constants"; import { isFeatureEnabled } from "@wso2is/core/helpers"; import { AlertInterface, @@ -174,15 +175,6 @@ export const ActionTypesListingPage: FunctionComponent ); - const resolveFeatureLabelClass = (featureStatus: FeatureStatusLabel): string => { - switch (featureStatus) { - case FeatureStatusLabel.BETA: - return "oxygen-chip-beta"; - case FeatureStatusLabel.COMING_SOON: - return "oxygen-chip-coming-soon"; - } - }; - const renderActionConfiguredStatus = (actionType: string): ReactElement => { let count: number = 0; @@ -238,7 +230,8 @@ export const ActionTypesListingPage: FunctionComponent, identifier: ActionsConstants.PRE_ISSUE_ACCESS_TOKEN_URL_PATH, @@ -247,7 +240,7 @@ export const ActionTypesListingPage: FunctionComponent, identifier: ActionsConstants.PRE_UPDATE_PASSWORD_URL_PATH, @@ -256,7 +249,7 @@ export const ActionTypesListingPage: FunctionComponent, identifier: ActionsConstants.PRE_UPDATE_PROFILE_URL_PATH, @@ -265,7 +258,7 @@ export const ActionTypesListingPage: FunctionComponent, identifier: ActionsConstants.PRE_REGISTRATION_URL_PATH, @@ -365,14 +358,11 @@ export const ActionTypesListingPage: FunctionComponent -
- - { t(cardProps.featureStatusLabel) } - -
+ diff --git a/features/admin.application-templates.v1/components/application-template-card.tsx b/features/admin.application-templates.v1/components/application-template-card.tsx index 8585d12bace..c9a13825c81 100644 --- a/features/admin.application-templates.v1/components/application-template-card.tsx +++ b/features/admin.application-templates.v1/components/application-template-card.tsx @@ -1,5 +1,5 @@ /** - * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * Copyright (c) 2024-2025, WSO2 LLC. (https://www.wso2.com). * * WSO2 LLC. licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except @@ -22,16 +22,20 @@ import Card from "@oxygen-ui/react/Card"; import CardContent from "@oxygen-ui/react/CardContent"; import Tooltip from "@oxygen-ui/react/Tooltip"; import Typography from "@oxygen-ui/react/Typography"; +import { AppState } from "@wso2is/admin.core.v1/store"; +import FeatureFlagConstants from "@wso2is/admin.feature-gate.v1/constants/feature-flag-constants"; +import useFeatureFlag from "@wso2is/admin.feature-gate.v1/hooks/use-feature-flag"; import { CustomAttributeInterface, ExtensionTemplateListInterface, ResourceTypes } from "@wso2is/admin.template-core.v1/models/templates"; import { ExtensionTemplateManagementUtils } from "@wso2is/admin.template-core.v1/utils/templates"; -import { IdentifiableComponentInterface } from "@wso2is/core/models"; +import { FeatureFlagsInterface, IdentifiableComponentInterface } from "@wso2is/core/models"; import classnames from "classnames"; import React, { FunctionComponent, MouseEvent, ReactElement, useMemo } from "react"; import { useTranslation } from "react-i18next"; +import { useSelector } from "react-redux"; import { ApplicationTemplateConstants } from "../constants/templates"; import { ApplicationTemplateFeatureStatus, SupportedTechnologyMetadataInterface } from "../models/templates"; import "./application-template-card.scss"; @@ -67,6 +71,13 @@ const ApplicationTemplateCard: FunctionComponent state.config.ui.features.applications.featureFlags); + + const featureFlag: string = useFeatureFlag(FeatureFlagConstants.FEATURE_FLAG_KEY_MAP.APPLICATION_TEMPLATES, + applicationFeatureFlagsConfig + ); + /** * Extract the supported technology details related to the current application template. */ @@ -98,7 +109,7 @@ const ApplicationTemplateCard: FunctionComponent = ( const brandingDisabledFeatures: string[] = useSelector((state: AppState) => state?.config?.ui?.features?.branding?.disabledFeatures); + const brandingFeatureFlags: FeatureFlagsInterface[] = useSelector( + (state: AppState) => state.config.ui.features?.branding?.featureFlags); const [ isBrandingAppsRedirect, setIsBrandingAppsRedirect ] = useState(false); @@ -238,10 +240,13 @@ const BrandingPageLayout: FunctionComponent = ( { resolveBrandingTitle() } { brandingMode === BrandingModes.APPLICATION && ( - ) } diff --git a/features/admin.branding.v1/components/branding-preference-tabs.tsx b/features/admin.branding.v1/components/branding-preference-tabs.tsx index 8e2645990ec..cee48a7ad52 100644 --- a/features/admin.branding.v1/components/branding-preference-tabs.tsx +++ b/features/admin.branding.v1/components/branding-preference-tabs.tsx @@ -1,5 +1,5 @@ /** - * Copyright (c) 2021-2024, WSO2 LLC. (https://www.wso2.com). + * Copyright (c) 2021-2025, WSO2 LLC. (https://www.wso2.com). * * WSO2 LLC. licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except @@ -17,10 +17,10 @@ */ import Button from "@oxygen-ui/react/Button"; -import Chip from "@oxygen-ui/react/Chip"; import { AppState } from "@wso2is/admin.core.v1/store"; import { commonConfig } from "@wso2is/admin.extensions.v1/configs"; -import { FeatureStatusLabel } from "@wso2is/admin.feature-gate.v1/models/feature-status"; +import FeatureFlagLabel from "@wso2is/admin.feature-gate.v1/components/feature-flag-label"; +import FeatureFlagConstants from "@wso2is/admin.feature-gate.v1/constants/feature-flag-constants"; import { BrandingPreferenceInterface, BrandingPreferenceThemeInterface, @@ -29,7 +29,7 @@ import { PreviewScreenType, PreviewScreenVariationType } from "@wso2is/common.branding.v1/models"; -import { IdentifiableComponentInterface } from "@wso2is/core/models"; +import { FeatureFlagsInterface, IdentifiableComponentInterface } from "@wso2is/core/models"; import { FormPropsInterface } from "@wso2is/form"; import { Heading, Link, ResourceTab, ResourceTabPaneInterface } from "@wso2is/react-components"; import cloneDeep from "lodash-es/cloneDeep"; @@ -164,7 +164,8 @@ export const BrandingPreferenceTabs: FunctionComponent state.config.ui.theme?.name); const supportEmail: string = useSelector((state: AppState) => state.config.deployment.extensions?.supportEmail as string); - const isSAASDeployment: boolean = useSelector((state: AppState) => state?.config?.ui?.isSAASDeployment); + const brandingFeatureFlags: FeatureFlagsInterface[] = useSelector( + (state: AppState) => state.config.ui.features?.branding?.featureFlags); const [ isSubmitting, setIsSubmitting ] = useState(isUpdating); const [ @@ -465,19 +466,22 @@ export const BrandingPreferenceTabs: FunctionComponent { t("branding:tabs.text.label") } - { isSAASDeployment && brandingMode !== BrandingModes.APPLICATION && ( - ) } - { brandingMode === BrandingModes.APPLICATION && ( - ) } diff --git a/features/admin.feature-gate.v1/components/feature-flag-label.tsx b/features/admin.feature-gate.v1/components/feature-flag-label.tsx new file mode 100644 index 00000000000..7e8146aedbe --- /dev/null +++ b/features/admin.feature-gate.v1/components/feature-flag-label.tsx @@ -0,0 +1,127 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import Chip from "@oxygen-ui/react/Chip"; +import { FeatureAccessConfigInterface, FeatureFlagsInterface } from "@wso2is/core/models"; +import React, { FunctionComponent, ReactElement } from "react"; +import { useTranslation } from "react-i18next"; +import useFeatureFlag from "../hooks/use-feature-flag"; +import { FeatureStatusLabel } from "../models/feature-status"; + +/** + * Proptypes for the feature flag label component. + */ +interface FeatureFlagLabelPropsInterface { + featureKey: string; + featureConfig?: FeatureAccessConfigInterface; + featureName?: string; + featureFlags?: FeatureFlagsInterface[]; + type?: "chip" | "ribbon"; +} + +/** + * Feature flag label component. + * + * @param featureFlags - Feature flags array. + * @param featureKey - Feature key to look up. + * @param featureConfig - Feature config object. + * @param featureName - Name (key) in the feature config object. + * @param type - Display type (chip/ribbon). + * + * @returns ReactElement + */ +const FeatureFlagLabel: FunctionComponent = ( + { + featureKey, + featureFlags, + featureConfig, + featureName, + type = "chip" + }: FeatureFlagLabelPropsInterface): ReactElement => { + + const { t } = useTranslation(); + + const label: string = useFeatureFlag(featureKey, featureFlags, featureConfig, featureName); + + /** + * Resolves the class for the feature flag label. + * + * @param flag - Feature flag. + * + * @returns string + */ + const resolveFeatureLabelClass = (flag: string): string => { + switch (flag) { + case FeatureStatusLabel.BETA: + return "oxygen-chip-beta"; + case FeatureStatusLabel.NEW: + return "oxygen-chip-new"; + case FeatureStatusLabel.COMING_SOON: + return "oxygen-chip-coming-soon"; + default: + return ""; + } + }; + + /** + * Resolves the label component based on the type. + * + * @param flag - Feature flag. + * + * @returns ReactElement + */ + const resolveLabelComponent = (flag: string): ReactElement => { + switch (type) { + case "chip": + return ( + + ); + case "ribbon": + return ( +
+ + { t(flag) } + +
+ ); + default: + return ( + + ); + } + }; + + return label ? resolveLabelComponent(FeatureStatusLabel[label]) : null; +}; + +export default FeatureFlagLabel; diff --git a/features/admin.feature-gate.v1/constants/feature-flag-constants.ts b/features/admin.feature-gate.v1/constants/feature-flag-constants.ts new file mode 100644 index 00000000000..7e2eb9ceb08 --- /dev/null +++ b/features/admin.feature-gate.v1/constants/feature-flag-constants.ts @@ -0,0 +1,54 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * Constants for feature flags. + */ +class FeatureFlagConstants { + + /** + * Private constructor to avoid object instantiation from outside + * the class. + */ + private constructor() {} + + /** + * Key map for feature flags. + */ + public static readonly FEATURE_FLAG_KEY_MAP: { [key: string]: string } = { + ACTIONS: "actions", + ACTIONS_TYPES_PRE_ISSUE_ACCESS_TOKEN: "actions.create.types.list.preIssueAccessToken", + ACTIONS_TYPES_PRE_REGISTRATION: "actions.create.types.list.preRegistration", + ACTIONS_TYPES_PRE_UPDATE_PASSWORD: "actions.create.types.list.preUpdatePassword", + ACTIONS_TYPES_PRE_UPDATE_PROFILE: "actions.create.types.list.preUpdateProfile", + APPLICATIONS: "application", + APPLICATION_BRANDING_TEXT: "branding.stylesAndText.application.text", + APPLICATION_TEMPLATES: "applications.templates", + BRANDING: "branding", + BRANDING_STYLES_AND_TEXT_TITLE: "branding.stylesAndText.application.title", + INSIGHTS: "insights", + LOGIN_AND_REGISTRATION: "loginAndRegistration", + LOGIN_AND_REGISTRATION_ORGANIZATION_DISCOVERY: "loginAndRegistration.organizationSettings.discovery", + LOGIN_AND_REGISTRATION_ORGANIZATION_IMPERSONATION: "loginAndRegistration.organizationSettings.impersonation", + ORGANIZATION_BRANDING_TEXT: "branding.stylesAndText.organization.text", + SMS_TEMPLATES: "smsTemplates", + USER_ROLES: "userRoles" + }; +} + +export default FeatureFlagConstants; diff --git a/features/admin.feature-gate.v1/hooks/use-feature-flag.tsx b/features/admin.feature-gate.v1/hooks/use-feature-flag.tsx new file mode 100644 index 00000000000..049b10a13cc --- /dev/null +++ b/features/admin.feature-gate.v1/hooks/use-feature-flag.tsx @@ -0,0 +1,63 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { FeatureAccessConfigInterface, FeatureFlagsInterface } from "@wso2is/core/models"; +import { useMemo } from "react"; + +/** + * Custom hook to get the status of a feature flag. + * + * @param featureKey - Feature key. + * @param featureFlags - Feature flags. + * @param featureConfig - Feature access configuration. + * @param featureName - Feature name. + * + * @returns Feature status flag. + */ +const useFeatureFlag = ( + featureKey: string, + featureFlags?: FeatureFlagsInterface[], + featureConfig?: FeatureAccessConfigInterface, + featureName?: string +): string | null => { + return useMemo(() => { + if (!featureKey) return null; + + // If feature flags are provided, find the flag directly. + if (featureFlags) { + return featureFlags.find( + (featureFlag: FeatureFlagsInterface) => featureFlag.feature === featureKey + )?.flag ?? null; + } + + // If feature config is provided with feature name. + if (featureConfig && featureName) { + const config: FeatureAccessConfigInterface = featureConfig[featureName]; + + if (!config) return null; + + return config.featureFlags?.find( + (featureFlag: FeatureFlagsInterface) => featureFlag.feature === featureKey + )?.flag ?? null; + } + + return null; + }, [ featureKey, featureName, featureFlags, featureConfig ]); +}; + +export default useFeatureFlag; diff --git a/features/admin.feature-gate.v1/public-api.ts b/features/admin.feature-gate.v1/public-api.ts index b1e492ea65b..e3f13c9ab11 100644 --- a/features/admin.feature-gate.v1/public-api.ts +++ b/features/admin.feature-gate.v1/public-api.ts @@ -18,5 +18,8 @@ export { default as FeatureGateConstants } from "./constants/feature-gate-constants"; export { default as useGetAllFeatures } from "./api/use-get-all-features"; +export { default as FeatureFlagLabel } from "./components/feature-flag-label"; +export { default as useFeatureFlag } from "./hooks/use-feature-flag"; +export { default as FeatureFlagConstants } from "./constants/feature-flag-constants"; export * from "./configs/endpoints"; export * from "./models/feature-status"; diff --git a/features/admin.server-configurations.v1/components/governance-connector-grid.tsx b/features/admin.server-configurations.v1/components/governance-connector-grid.tsx index d6ef209011d..85bcb4af7ea 100644 --- a/features/admin.server-configurations.v1/components/governance-connector-grid.tsx +++ b/features/admin.server-configurations.v1/components/governance-connector-grid.tsx @@ -1,5 +1,5 @@ /** - * Copyright (c) 2023-2024, WSO2 LLC. (https://www.wso2.com). + * Copyright (c) 2023-2025, WSO2 LLC. (https://www.wso2.com). * * WSO2 LLC. licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except @@ -38,16 +38,17 @@ import { UserGearIcon, UserPlusIcon } from "@oxygen-ui/react-icons"; -import { AppConstants, history } from "@wso2is/admin.core.v1"; +import { AppConstants, AppState, history } from "@wso2is/admin.core.v1"; import { serverConfigurationConfig } from "@wso2is/admin.extensions.v1"; -import { FeatureStatusLabel } from "@wso2is/admin.feature-gate.v1/models/feature-status"; -import { IdentifiableComponentInterface, LoadableComponentInterface } from "@wso2is/core/models"; +import FeatureFlagLabel from "@wso2is/admin.feature-gate.v1/components/feature-flag-label"; +import { FeatureFlagsInterface, IdentifiableComponentInterface, LoadableComponentInterface } from "@wso2is/core/models"; import { ContentLoader } from "@wso2is/react-components"; import React, { FunctionComponent, ReactElement, useMemo } from "react"; -import { useTranslation } from "react-i18next"; import "./governance-connector-grid.scss"; +import { useSelector } from "react-redux"; import { ServerConfigurationsConstants } from "../constants/server-configurations-constants"; import { GovernanceConnectorCategoryInterface, GovernanceConnectorInterface } from "../models/governance-connectors"; + /** * Props for the Governance connector configuration categories page. */ @@ -81,7 +82,8 @@ const GovernanceConnectorCategoriesGrid: FunctionComponent state.config.ui.features?.loginAndRegistration?.featureFlags); /** * Combine the connectors and dynamic connectors and group them by category. @@ -213,15 +215,6 @@ const GovernanceConnectorCategoriesGrid: FunctionComponent { - switch (featureStatus) { - case FeatureStatusLabel.BETA: - return "oxygen-chip-beta"; - case FeatureStatusLabel.NEW: - return "oxygen-chip-new"; - } - }; - return (
{ combinedConnectors?.map((category: GovernanceConnectorCategoryInterface, index: number) => { @@ -263,17 +256,11 @@ const GovernanceConnectorCategoriesGrid: FunctionComponent - - { t(connector.status) } - -
+ ) }
diff --git a/features/admin.server-configurations.v1/utils/governance-connector-utils.ts b/features/admin.server-configurations.v1/utils/governance-connector-utils.ts index 840fddf4c3f..02e458b1245 100644 --- a/features/admin.server-configurations.v1/utils/governance-connector-utils.ts +++ b/features/admin.server-configurations.v1/utils/governance-connector-utils.ts @@ -1,5 +1,5 @@ /** - * Copyright (c) 2022-2023, WSO2 LLC. (https://www.wso2.com). + * Copyright (c) 2022-2025, WSO2 LLC. (https://www.wso2.com). * * WSO2 LLC. licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except @@ -18,6 +18,7 @@ import { AppConstants, store } from "@wso2is/admin.core.v1"; import { serverConfigurationConfig } from "@wso2is/admin.extensions.v1"; +import FeatureFlagConstants from "@wso2is/admin.feature-gate.v1/constants/feature-flag-constants"; import { FeatureStatusLabel } from "@wso2is/admin.feature-gate.v1/models/feature-status"; import { IdentityAppsApiException } from "@wso2is/core/exceptions"; import { AlertLevels } from "@wso2is/core/models"; @@ -390,7 +391,7 @@ export class GovernanceConnectorUtils { header: I18n.instance.t("pages:emailDomainDiscovery.title"), id: ServerConfigurationsConstants.EMAIL_DOMAIN_DISCOVERY, route: AppConstants.getPaths().get("ORGANIZATION_DISCOVERY_DOMAINS"), - status: FeatureStatusLabel.NEW, + status: FeatureFlagConstants.FEATURE_FLAG_KEY_MAP.LOGIN_AND_REGISTRATION_ORGANIZATION_DISCOVERY, testId: "email-domain-discovery-card" }, { @@ -398,7 +399,8 @@ export class GovernanceConnectorUtils { header: I18n.instance.t("pages:impersonation.title"), id: ServerConfigurationsConstants.IMPERSONATION, route: AppConstants.getPaths().get("IMPERSONATION"), - status: FeatureStatusLabel.NEW, + status: FeatureFlagConstants.FEATURE_FLAG_KEY_MAP + .LOGIN_AND_REGISTRATION_ORGANIZATION_IMPERSONATION, testId: "impersonation-card" } ], diff --git a/modules/core/src/helpers/__mocks__/deployment.config.json b/modules/core/src/helpers/__mocks__/deployment.config.json index 7be2dfdf27d..99525b584d7 100644 --- a/modules/core/src/helpers/__mocks__/deployment.config.json +++ b/modules/core/src/helpers/__mocks__/deployment.config.json @@ -42,370 +42,1292 @@ }, "tenantResolutionStrategy": "id_token", "ui": { - "appCopyright": "WSO2 Identity Server ${copyright} ${year}", - "appTitle": "Console | WSO2 Identity Server", - "appName": "Console", - "applicationTemplateLoadingStrategy": "LOCAL", + "administratorRoleDisplayName": "Administrator", + "announcements": [], + "appCopyright": "${copyright} ${year} WSO2 LLC.", + "appFaviconPath": "/assets/images/branding/favicon.ico", "appLogoPath": "/assets/images/branding/logo.svg", + "appName": "Console", + "appTitle": "WSO2 Identity Server Console", + "appWhiteLogoPath": "/assets/images/branding/logo-inverted.svg", + "connectionResourcesUrl": "", + "cookiePolicyUrl": "/authenticationendpoint/cookie_policy.do", + "emailTemplates": { + "defaultLogoUrl": "/libs/themes/default/assets/images/branding/logo.svg", + "defaultWhiteLogoUrl": "/libs/themes/default/assets/images/branding/logo-inverted.svg" + }, + "enableCustomEmailTemplates": true, + "enableCustomSmsTemplates": true, + "enableEmailDomain": false, + "enableIdentityClaims": true, "features": { - "applications": { + "accountLogin": { + "disabledFeatures": [], + "enabled": true, + "scopes": { + "update": [ + "internal_config_mgt_update" + ] + } + }, + "accountRecovery": { "disabledFeatures": [], "enabled": true, "scopes": { + "create": [], + "delete": [], "feature": [ - "console:applications" + "console:loginAndRegistration" + ], + "read": [ + "internal_governance_view" ], + "update": [ + "internal_governance_update" + ] + } + }, + "accountSecurity": { + "disabledFeatures": [], + "enabled": true, + "scopes": { + "create": [], + "delete": [], + "feature": [ + "console:loginAndRegistration" + ], + "read": [ + "internal_governance_view" + ], + "update": [ + "internal_governance_update" + ] + } + }, + "actions": { + "disabledFeatures": [ + "actions.filterPreRegistration", + "actions.filterPreUpdateProfile" + ], + "enabled": true, + "featureFlags": [ + { + "feature": "actions", + "flag": "" + }, + { + "feature": "actions.create.types.list.preIssueAccessToken", + "flag": "" + }, + { + "feature": "actions.create.types.list.preUpdatePassword", + "flag": "" + }, + { + "feature": "actions.create.types.list.preUpdateProfile", + "flag": "" + }, + { + "feature": "actions.create.types.list.preRegistration", + "flag": "" + } + ], + "scopes": { + "create": [ + "internal_action_mgt_create" + ], + "delete": [ + "internal_action_mgt_delete" + ], + "feature": [ + "console:actions" + ], + "read": [ + "internal_action_mgt_view" + ], + "update": [ + "internal_action_mgt_update" + ] + } + }, + "adminAdvisoryBanner": { + "disabledFeatures": [], + "enabled": true, + "scopes": {} + }, + "administrators": { + "disabledFeatures": [], + "enabled": false, + "scopes": { + "create": [], + "delete": [], + "read": [], + "update": [] + } + }, + "ai": { + "disabledFeatures": [], + "enabled": false, + "scopes": { + "create": [], + "delete": [], + "feature": [], + "read": [], + "update": [] + } + }, + "analytics": { + "disabledFeatures": [], + "enabled": true, + "scopes": { + "create": [], + "delete": [], + "feature": [ + "console:loginAndRegistration" + ], + "read": [ + "internal_governance_view" + ], + "update": [ + "internal_governance_update" + ] + } + }, + "apiResources": { + "disabledFeatures": [], + "enabled": true, + "scopes": { + "create": [ + "internal_api_resource_create" + ], + "delete": [ + "internal_api_resource_delete" + ], + "feature": [ + "console:apiResources" + ], + "read": [ + "internal_api_resource_view" + ], + "update": [ + "internal_api_resource_update" + ] + } + }, + "applicationRoles": { + "disabledFeatures": [], + "enabled": false, + "scopes": { + "create": [], + "delete": [], + "read": [], + "update": [] + } + }, + "applications": { + "disabledFeatures": [ + "applications.loginFlow.ai", + "applications.loginFlow.legacyEditor" + ], + "enabled": true, + "featureFlags": [ + { + "feature": "applications", + "flag": "" + }, + { + "feature": "applications.templates", + "flag": "" + }, + { + "feature": "applications.create.templates.list.m2m", + "flag": "" + }, + { + "feature": "applications.create.templates.list.google", + "flag": "" + }, + { + "feature": "applications.create.templates.list.microsoft", + "flag": "" + }, + { + "feature": "applications.create.templates.list.salesforce", + "flag": "" + }, + { + "feature": "applications.create.templates.list.zoom", + "flag": "" + }, + { + "feature": "applications.create.templates.list.slack", + "flag": "" + }, + { + "feature": "applications.create.templates.list.slack", + "flag": "" + }, + { + "feature": "applications.edit.general.branding", + "flag": "" + } + ], + "scopes": { "create": [ "internal_application_mgt_create" ], + "delete": [ + "internal_application_mgt_delete" + ], + "feature": [ + "console:applications" + ], "read": [ - "internal_cors_origins_view", "internal_application_mgt_view", "internal_claim_meta_view", + "internal_idp_view", "internal_role_mgt_view", - "internal_userstore_view", - "internal_idp_view" + "internal_userstore_view" ], "update": [ "internal_application_mgt_update" + ] + } + }, + "approvals": { + "disabledFeatures": [], + "enabled": false, + "scopes": { + "create": [ + "internal_humantask_view" ], "delete": [ - "internal_application_mgt_delete" + "internal_humantask_view" + ], + "feature": [ + "console:workflowApprovals" + ], + "read": [ + "internal_humantask_view" + ], + "update": [ + "internal_humantask_view" ] } }, - "approvals": { + "attributeDialects": { + "disabledFeatures": [ + "attributeDialects.distinct.attribute.profiles" + ], + "enabled": true, + "scopes": { + "create": [ + "internal_claim_meta_create" + ], + "delete": [ + "internal_claim_meta_delete" + ], + "feature": [ + "console:attributes" + ], + "read": [ + "internal_claim_meta_view", + "internal_userstore_view" + ], + "update": [ + "internal_claim_meta_update" + ] + } + }, + "auditLogs": { "disabledFeatures": [], "enabled": true, + "scopes": { + "update": [ + "internal_application_mgt_view" + ] + } + }, + "branding": { + "disabledFeatures": [ + "branding.ai", + "branding.hostnameUrlBranding" + ], + "enabled": true, + "featureFlags": [ + { + "feature": "branding", + "flag": "" + }, + { + "feature": "branding.stylesAndText", + "flag": "" + }, + { + "feature": "branding.emailTemplates", + "flag": "" + }, + { + "feature": "branding.stylesAndText.application.title", + "flag": "" + }, + { + "feature": "branding.stylesAndText.application.text", + "flag": "" + }, + { + "feature": "branding.stylesAndText.organization.text", + "flag": "" + } + ], "scopes": { "create": [ - "internal_humantask_view" + "internal_branding_preference_update" + ], + "delete": [ + "internal_branding_preference_update" + ], + "feature": [ + "console:branding" + ], + "read": [ + "internal_application_mgt_view" + ], + "update": [ + "internal_branding_preference_update" + ] + } + }, + "bulkUserImport": { + "disabledFeatures": [], + "enabled": true, + "fileImportTimeout": 90000, + "scopes": { + "create": [ + "internal_claim_meta_view", + "internal_role_mgt_view", + "internal_user_mgt_create", + "internal_user_mgt_delete", + "internal_user_mgt_list", + "internal_user_mgt_view", + "internal_userstore_view" + ], + "delete": [], + "read": [], + "update": [] + }, + "userLimit": 50 + }, + "certificates": { + "disabledFeatures": [], + "enabled": false, + "scopes": { + "create": [ + "internal_keystore_update" + ], + "delete": [ + "internal_keystore_update" + ], + "feature": [ + "console:certificates" + ], + "read": [ + "internal_keystore_view" + ], + "update": [ + "internal_keystore_update" + ] + } + }, + "consoleSettings": { + "disabledFeatures": [ + "consoleSettings.invitedExternalAdmins", + "consoleSettings.privilegedUsers" + ], + "enabled": true, + "scopes": { + "create": [ + "internal_role_mgt_create" + ], + "delete": [], + "feature": [ + "console:settings" + ], + "read": [ + "internal_application_mgt_view", + "internal_governance_view", + "internal_group_mgt_view", + "internal_idp_view", + "internal_role_mgt_view", + "internal_session_view", + "internal_user_mgt_list", + "internal_user_mgt_view", + "internal_userstore_view" + ], + "update": [ + "internal_application_mgt_update", + "internal_user_mgt_update" + ] + } + }, + "emailProviders": { + "disabledFeatures": [], + "enabled": true, + "scopes": { + "create": [ + "internal_notification_senders_create" + ], + "delete": [ + "internal_notification_senders_delete" + ], + "read": [ + "internal_notification_senders_view" + ], + "update": [ + "internal_notification_senders_update" + ] + } + }, + "emailTemplates": { + "disabledFeatures": [], + "enabled": true, + "scopes": { + "create": [ + "internal_email_mgt_create" + ], + "delete": [ + "internal_email_mgt_delete" + ], + "feature": [ + "console:emailTemplates" + ], + "read": [ + "internal_email_mgt_view" + ], + "update": [ + "internal_email_mgt_update" + ] + } + }, + "eventPublishing": { + "disabledFeatures": [], + "enabled": true, + "scopes": { + "create": [ + "internal_event_config_update" + ], + "delete": [ + "internal_event_config_update" + ], + "feature": [ + "console:eventPublishing" + ], + "read": [ + "internal_event_config_view" + ], + "update": [ + "internal_event_config_update" + ] + } + }, + "gettingStarted": { + "disabledFeatures": [], + "enabled": true, + "scopes": { + "create": [ + "internal_application_mgt_create", + "internal_group_mgt_create", + "internal_idp_create", + "internal_user_mgt_create" + ], + "delete": [], + "feature": [ + "console:home" + ], + "read": [], + "update": [ + "internal_application_mgt_update" + ] + } + }, + "governanceConnectors": { + "deprecatedFeaturesToShow": [], + "disabledFeatures": [], + "enabled": true, + "scopes": { + "create": [], + "delete": [], + "feature": [ + "console:loginAndRegistration" + ], + "read": [ + "internal_governance_view" + ], + "update": [ + "internal_config_update", + "internal_governance_update", + "internal_validation_rule_mgt_update" + ] + } + }, + "groups": { + "disabledFeatures": [ "groups.add", "groups.edit", "groups.edit.generalSettings" ], + "enabled": true, + "scopes": { + "create": [ + "internal_group_mgt_create" + ], + "delete": [ + "internal_group_mgt_delete" + ], + "feature": [ + "console:groups" + ], + "read": [ + "internal_group_mgt_view", + "internal_role_mgt_view", + "internal_user_mgt_list", + "internal_user_mgt_view", + "internal_userstore_view" + ], + "update": [ + "internal_group_mgt_update" + ] + } + }, + "guestUser": { + "disabledFeatures": [], + "enabled": true, + "scopes": { + "create": [ + "internal_guest_mgt_invite_add" + ], + "delete": [ + "internal_guest_mgt_invite_delete", + "internal_guest_mgt_user_delete" + ], + "read": [ + "internal_guest_mgt_invite_list" + ], + "update": [ + "internal_guest_mgt_invite_update" + ] + } + }, + "identityProviderGroups": { + "disabledFeatures": [], + "enabled": true, + "scopes": {} + }, + "identityProviders": { + "disabledFeatures": [], + "enabled": true, + "scopes": { + "create": [ + "internal_idp_create" + ], + "delete": [ + "internal_idp_delete" + ], + "feature": [ + "console:idps" + ], + "read": [ + "internal_claim_meta_view", + "internal_idp_view", + "internal_role_mgt_view", + "internal_userstore_view" + ], + "update": [ + "internal_idp_update" + ] + } + }, + "identityVerificationProviders": { + "enabled": true, + "scopes": { + "create": [ + "internal_idvp_add" + ], + "delete": [ + "internal_idvp_delete" + ], + "feature": [ + "console:idvps" + ], + "read": [ + "internal_idvp_view" + ], + "update": [ + "internal_idvp_update" + ] + } + }, + "insights": { + "disabledFeatures": [], + "enabled": false, + "featureFlags": [ + { + "feature": "insights", + "flag": "" + } + ], + "scopes": {} + }, + "internalNotificationSending": { + "disabledFeatures": [], + "enabled": true, + "scopes": { + "create": [], + "delete": [], + "feature": [ + "console:loginAndRegistration" + ], + "read": [ + "internal_governance_view" + ], + "update": [ + "internal_governance_update" + ] + } + }, + "loginAndRegistration": { + "disabledFeatures": [], + "enabled": true, + "featureFlags": [ + { + "feature": "loginAndRegistration", + "flag": "" + }, + { + "feature": "loginAndRegistration.organizationSettings.discovery", + "flag": "" + }, + { + "feature": "loginAndRegistration.organizationSettings.impersonation", + "flag": "" + } + ], + "scopes": { + "create": [], + "delete": [], + "feature": [ + "console:loginAndRegistration" + ], + "read": [ + "internal_governance_view" + ], + "update": [ + "internal_config_update", + "internal_governance_update", + "internal_validation_rule_mgt_update" + ] + } + }, + "logs": { + "disabledFeatures": [], + "enabled": false, + "scopes": { + "update": [ + "internal_application_mgt_view" + ] + } + }, + "myAccount": { + "disabledFeatures": [], + "enabled": false, + "scopes": { + "create": [], + "delete": [], + "read": [], + "update": [] + } + }, + "notificationChannels": { + "disabledFeatures": [], + "enabled": true, + "scopes": { + "create": [ + "internal_notification_senders_create" + ], + "delete": [ + "internal_notification_senders_delete" + ], + "feature": [ + "console:notificationChannels" + ], + "read": [ + "internal_notification_senders_view" + ], + "update": [ + "internal_notification_senders_update" + ] + } + }, + "oidcScopes": { + "disabledFeatures": [], + "enabled": true, + "scopes": { + "create": [ + "internal_oidc_scope_mgt_create" + ], + "delete": [ + "internal_oidc_scope_mgt_delete" + ], + "feature": [ + "console:scopes:oidc" + ], + "read": [ + "internal_claim_meta_view", + "internal_oidc_scope_mgt_view" + ], + "update": [ + "internal_oidc_scope_mgt_update" + ] + } + }, + "organizationDiscovery": { + "disabledFeatures": [], + "enabled": true, + "scopes": { + "create": [ + "internal_organization_config_add", + "internal_organization_discovery_update" + ], + "delete": [ + "internal_organization_config_delete", + "internal_organization_discovery_delete" + ], + "feature": [ + "console:organizationDiscovery" + ], + "read": [ + "internal_organization_config_view", + "internal_organization_discovery_view", + "internal_organization_view" + ], + "update": [ + "internal_organization_discovery_update" + ] + } + }, + "organizations": { + "disabledFeatures": [], + "enabled": true, + "scopes": { + "create": [ + "internal_organization_create" + ], + "delete": [ + "internal_organization_delete" + ], + "feature": [ + "console:organizations" + ], + "read": [ + "internal_organization_view" + ], + "update": [ + "internal_organization_update" + ] + } + }, + "parentUserInvitation": { + "disabledFeatures": [], + "enabled": true, + "scopes": { + "create": [ + "internal_guest_mgt_invite_add" + ], + "delete": [ + "internal_guest_mgt_invite_delete", + "internal_guest_mgt_user_delete" + ], + "read": [ + "internal_guest_mgt_invite_list" + ], + "update": [ + "internal_guest_mgt_invite_update" + ] + } + }, + "policyAdministration":{ + "disabledFeatures": [], + "enabled": false, + "scopes": { + "create": [], + "delete": [], + "feature": [], + "read": [], + "update": [] + } + }, + "remoteFetchConfig": { + "disabledFeatures": [], + "enabled": false, + "scopes": { + "create": [ + "internal_identity_mgt_create", + "internal_identity_mgt_delete", + "internal_identity_mgt_update", + "internal_identity_mgt_view" + ], + "delete": [ + "internal_identity_mgt_create", + "internal_identity_mgt_delete", + "internal_identity_mgt_update", + "internal_identity_mgt_view" ], "read": [ - "internal_humantask_view" + "internal_identity_mgt_create", + "internal_identity_mgt_delete", + "internal_identity_mgt_update", + "internal_identity_mgt_view" ], "update": [ - "internal_humantask_view" - ], - "delete": [ - "internal_humantask_view" + "internal_identity_mgt_create", + "internal_identity_mgt_delete", + "internal_identity_mgt_update", + "internal_identity_mgt_view" ] } }, - "attributeDialects": { + "remoteLogging": { + "disabledFeatures": [], "enabled": true, + "scopes": {} + }, + "residentOutboundProvisioning": { "disabledFeatures": [], + "enabled": true, "scopes": { + "create": [], + "delete": [], "feature": [ - "console:attributes" - ], - "create": [ - "internal_claim_meta_create" + "console:residentOutboundProvisioning" ], "read": [ - "internal_userstore_view", - "internal_claim_meta_view" + "internal_application_mgt_view", + "internal_idp_view" ], "update": [ - "internal_claim_meta_update" - ], - "delete": [ - "internal_claim_meta_delete" + "internal_application_mgt_update" ] } }, - "certificates": { - "enabled": true, + "ruleBasedPasswordExpiry": { "disabledFeatures": [], + "enabled": true, "scopes": { - "create": [ - "internal_keystore_update" - ], + "create": [], + "delete": [], + "feature": [], "read": [ - "internal_keystore_view" + "internal_governance_view", + "internal_group_mgt_view", + "internal_role_mgt_view" ], "update": [ - "internal_keystore_update" - ], - "delete": [ - "internal_keystore_update" + "internal_config_update", + "internal_governance_update", + "internal_validation_rule_mgt_update" ] } }, - "emailTemplates": { + "saml2Configuration": { + "disabledFeatures": [], "enabled": true, + "scopes": { + "create": [], + "delete": [], + "read": [], + "update": [] + } + }, + "secretsManagement": { "disabledFeatures": [], + "enabled": false, "scopes": { "create": [ - "internal_email_mgt_create" + "internal_secret_mgt_add" + ], + "delete": [ + "internal_secret_mgt_delete" + ], + "feature": [ + "console:secretsManagement" ], "read": [ - "internal_email_mgt_view" + "internal_secret_mgt_view" ], "update": [ - "internal_email_mgt_update" - ], - "delete": [ - "internal_email_mgt_delete" + "internal_secret_mgt_update" ] } }, - "governanceConnectors": { - "enabled": true, + "server": { "disabledFeatures": [], + "enabled": true, "scopes": { "create": [], + "delete": [], + "feature": [ + "console:server" + ], "read": [ "internal_governance_view" ], "update": [ "internal_governance_update" - ], - "delete": [] + ] } }, - "groups": { + "sessionManagement": { + "disabledFeatures": [], + "enabled": true, + "scopes": { + "create": [], + "delete": [], + "read": [], + "update": [] + } + }, + "smsProviders": { + "disabledFeatures": [ + "choreoAsSMSProvider" + ], "enabled": true, - "disabledFeatures": [ "groups.add", "groups.edit", "groups.edit.generalSettings" ], "scopes": { - "feature": [ - "console:groups" - ], "create": [ - "internal_group_mgt_create" + "internal_notification_senders_create" + ], + "delete": [ + "internal_notification_senders_delete" ], "read": [ - "internal_user_mgt_view", - "internal_role_mgt_view", - "internal_group_mgt_view", - "internal_userstore_view" + "internal_notification_senders_view" ], "update": [ - "internal_group_mgt_update" - ], - "delete": [ - "internal_group_mgt_delete" + "internal_notification_senders_update" ] } }, - "identityProviders": { + "smsTemplates": { "disabledFeatures": [], "enabled": true, + "featureFlags": [ + { + "feature": "smsTemplates", + "flag": "" + } + ], "scopes": { - "feature": [ - "console:idps" - ], "create": [ - "internal_idp_create" + "internal_template_mgt_create" + ], + "delete": [ + "internal_template_mgt_delete" + ], + "feature": [ + "console:smsTemplates" ], "read": [ - "internal_userstore_view", - "internal_idp_view", - "internal_role_mgt_view", - "internal_claim_meta_view" + "internal_template_mgt_view" ], "update": [ - "internal_idp_update" - ], - "delete": [ - "internal_idp_delete" + "internal_template_mgt_update" ] } }, - "oidcScopes": { + "tenants": { + "disabledFeatures": [ + "tenants.add.tenant.from.dropdown", + "tenants.deletion", + "tenants.make.default", + "tenants.organizations.quick.nav.from.dropdown" + ], "enabled": true, - "disabledFeatures": [], "scopes": { - "feature": [ - "console:scopes:oidc" - ], "create": [ - "internal_oidc_scope_mgt_create" + "internal_create_tenants" + ], + "delete": [ + "internal_modify_tenants" ], "read": [ - "internal_oidc_scope_mgt_view", - "internal_claim_meta_view" + "internal_list_tenants" ], "update": [ - "internal_oidc_scope_mgt_update" - ], - "delete": [ - "internal_oidc_scope_mgt_delete" + "internal_modify_tenants" ] } }, - "secretsManagement": { - "enabled": true, + "tryIt": { "disabledFeatures": [], + "enabled": true, "scopes": { "create": [ - "internal_secret_mgt_add" + "internal_application_mgt_create" + ], + "delete": [ + "internal_application_mgt_delete" ], "read": [ - "internal_secret_mgt_view" + "internal_application_mgt_view", + "internal_claim_meta_view", + "internal_cors_origins_view", + "internal_idp_view", + "internal_role_mgt_view", + "internal_userstore_view" ], "update": [ - "internal_secret_mgt_update" - ], - "delete": [ - "internal_secret_mgt_delete" + "internal_application_mgt_update" ] } }, - "remoteFetchConfig": { - "enabled": true, + "userOnboarding": { "disabledFeatures": [], + "enabled": true, "scopes": { - "create": [ - "internal_identity_mgt_view", - "internal_identity_mgt_update", - "internal_identity_mgt_create", - "internal_identity_mgt_delete" + "create": [], + "delete": [], + "feature": [ + "console:loginAndRegistration" ], "read": [ - "internal_identity_mgt_view", - "internal_identity_mgt_update", - "internal_identity_mgt_create", - "internal_identity_mgt_delete" + "internal_governance_view" ], "update": [ - "internal_identity_mgt_view", - "internal_identity_mgt_update", - "internal_identity_mgt_create", - "internal_identity_mgt_delete" - ], - "delete": [ - "internal_identity_mgt_view", - "internal_identity_mgt_update", - "internal_identity_mgt_create", - "internal_identity_mgt_delete" + "internal_governance_update" ] } }, - "roles": { - "enabled": true, + "userRoles": { "disabledFeatures": [], + "enabled": true, + "featureFlags": [ + { + "feature": "userRoles", + "flag": "" + } + ], "scopes": { - "feature": [ - "console:roles" - ], "create": [ "internal_role_mgt_create" ], + "delete": [ + "internal_role_mgt_delete" + ], + "feature": [ + "console:roles" + ], "read": [ - "internal_user_mgt_view", + "internal_application_mgt_view", + "internal_group_mgt_view", + "internal_idp_view", "internal_role_mgt_view", - "internal_userstore_view", - "internal_group_mgt_view" + "internal_user_mgt_list", + "internal_user_mgt_view", + "internal_userstore_view" ], "update": [ "internal_role_mgt_update" - ], - "delete": [ - "internal_role_mgt_delete" ] } }, "userStores": { + "disabledFeatures": [ + "userStores.type.remote" + ], "enabled": true, - "disabledFeatures": [], "scopes": { "create": [ "internal_userstore_create" ], + "delete": [ + "internal_userstore_delete" + ], + "feature": [ + "console:userstores" + ], "read": [ "internal_userstore_view" ], "update": [ "internal_userstore_update" + ] + } + }, + "userV1Roles": { + "disabledFeatures": [], + "enabled": true, + "scopes": { + "create": [ + "internal_role_mgt_create" ], "delete": [ - "internal_userstore_delete" + "internal_role_mgt_delete" + ], + "feature": [ + "console:roles" + ], + "read": [ + "internal_group_mgt_view", + "internal_permission_mgt_view", + "internal_role_mgt_view", + "internal_user_mgt_list", + "internal_user_mgt_view", + "internal_userstore_view" + ], + "update": [ + "internal_role_mgt_update" ] } }, "users": { - "enabled": true, "disabledFeatures": [ "users.add" ], + "enabled": true, "scopes": { - "feature": [ - "console:users" - ], "create": [ "internal_user_mgt_create" ], + "delete": [ + "internal_user_mgt_delete" + ], + "feature": [ + "console:users" + ], "read": [ - "internal_userstore_view", - "internal_role_mgt_view", - "internal_group_mgt_view", "internal_governance_view", + "internal_group_mgt_view", "internal_login", - "internal_user_mgt_view", + "internal_role_mgt_view", + "internal_session_view", "internal_user_mgt_list", - "internal_session_view" + "internal_user_mgt_view", + "internal_userstore_view" ], "update": [ - "internal_user_mgt_update", - "internal_session_delete" - ], - "delete": [ - "internal_user_mgt_delete" + "internal_session_delete", + "internal_user_mgt_update" ] } + }, + "wsFedConfiguration": { + "disabledFeatures": [], + "enabled": true, + "scopes": { + "create": [], + "delete": [], + "read": [], + "update": [] + } + } + }, + "governanceConnectors": { + "loginAttempts": { + "disabledFeatures": [] } }, - "hiddenUserStores": [ ], + "gravatarConfig": { + "fallback": "404" + }, + "hiddenApplicationTemplates": [], + "hiddenAuthenticators": [ + "BasicAuthRequestPathAuthenticator", + "OAuthRequestPathAuthenticator" + ], + "hiddenConnectionTemplates": [ + "hypr-idp", + "swe-idp" + ], + "hiddenUserStores": [], + "i18nConfigs": { + "langAutoDetectEnabled": false, + "showLanguageSwitcher": false + }, "identityProviderTemplates": { - "enterpriseOIDC": { - "enabled": true - }, - "enterpriseSAML": { - "enabled": true - }, - "facebook": { + "github": { "enabled": true }, - "google": { + "hypr": { "enabled": true }, - "github": { - "enabled": false - }, - "microsoft": { + "trustedTokenIssuer": { "enabled": true } }, - "gravatarConfig": { - "fallback": "404" - }, - "hiddenAuthenticators": [], - "hiddenConnectionTemplates": [], - "i18nConfigs": { - "showLanguageSwitcher": false, - "langAutoDetectEnabled":false - }, - "isCookieConsentBannerEnabled": false, - "isGroupAndRoleSeparationEnabled": true, - "isSignatureValidationCertificateAliasEnabled" : false, + "isClaimUniquenessValidationEnabled": false, "isClientSecretHashEnabled": false, + "isCookieConsentBannerEnabled": true, + "isCustomClaimMappingEnabled": true, + "isCustomClaimMappingMergeEnabled": true, "isDefaultDialectEditingEnabled": false, - "isDialectAddingEnabled": true, + "isDialectAddingEnabled": false, + "isEditingSystemRolesAllowed": true, + "isFeatureGateEnabled": false, + "isGOTEnabledForSuperTenantOnly": true, + "isGroupAndRoleSeparationEnabled": true, + "isHeaderAvatarLabelAllowed": false, "isLeftNavigationCategorized": true, - "isRequestPathAuthenticationEnabled": true, - "listAllAttributeDialects": false, - "privacyPolicyConfigs": { - "visibleOnFooter": true + "isMarketingConsentBannerEnabled": false, + "isMultipleEmailsAndMobileNumbersEnabled": true, + "isPasswordInputValidationEnabled": true, + "isRequestPathAuthenticationEnabled": false, + "isSAASDeployment": false, + "isSignatureValidationCertificateAliasEnabled": false, + "isTrustedAppConsentRequired": false, + "isXacmlConnectorEnabled": false, + "legacyMode": { + "applicationListSystemApps": false, + "applicationSystemAppsSettings": false, + "roleMapping": false }, + "listAllAttributeDialects": true, + "multiTenancy": { + "isTenantDomainDotExtensionMandatory": true, + "tenantDomainIllegalCharactersRegex": ".*[^a-z0-9._-].*", + "tenantDomainRegex": "" + }, + "passwordPolicyConfigs": { + "maxPasswordAllowedLength": 64 + }, + "privacyPolicyConfigs": {}, "productName": "WSO2 Identity Server", "productVersionConfig": { - "allowSnapshot": true, - "textCase": "uppercase", - "labelColor": "primary" + "productVersion": "" + }, + "routes": { + "organizationEnabledRoutes": [ + "apiResources", + "applications", + "attributeDialects", + "branding", + "consoleSettings", + "emailTemplates", + "gettingStarted", + "governanceConnectors", + "groups", + "identityProviders", + "organizations", + "roles", + "smsTemplates", + "userRoles", + "userStores", + "users" + ] }, "selfAppIdentifier": "Console", - "systemAppsIdentifiers": [ "Console", "My Account" ], + "showAppSwitchButton": true, + "showSmsOtpPwdRecoveryFeatureStatusChip": false, + "showStatusLabelForNewAuthzRuntimeFeatures": false, + "systemAppsIdentifiers": [ + "Console", + "My Account" + ], "theme": { - "name": "default" - } + "name": "wso2is" + }, + "useRoleClaimAsGroupClaim": false } } diff --git a/modules/core/src/models/config.ts b/modules/core/src/models/config.ts index 614cc7233fe..3f3883063e2 100644 --- a/modules/core/src/models/config.ts +++ b/modules/core/src/models/config.ts @@ -336,12 +336,30 @@ export interface FeatureAccessConfigInterface { * Enable the feature. */ enabled?: boolean; + /** + * Enable the feature flags. + */ + featureFlags?: FeatureFlagsInterface[]; /** * Enable the tour option */ tryittourenabled?: boolean; } +/** + * Interface for feature flags. + */ +export interface FeatureFlagsInterface { + /** + * Identifier of the feature. + */ + feature: string; + /** + * Value of the feature flag. + */ + flag: string; +} + export interface DeprecatedFeatureInterface { /** * Name of the deprecated feature. diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 04951e565a6..df00fc776b1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2504,6 +2504,9 @@ importers: '@wso2is/admin.core.v1': specifier: ^2.37.12 version: link:../admin.core.v1 + '@wso2is/admin.feature-gate.v1': + specifier: ^1.4.94 + version: link:../admin.feature-gate.v1 '@wso2is/admin.template-core.v1': specifier: ^1.5.58 version: link:../admin.template-core.v1 @@ -25062,7 +25065,7 @@ packages: resolution: {integrity: sha512-KjzRUts2i/ODlMfywhFTqTzQl+Cr9nlDSZxJcnYjrbOV/iRyQNBTDoiFJt+XEdRi0fZBHnk74AFbnP56ehybsA==} engines: {node: '>=12.0.0'} peerDependencies: - '@types/react': 18.0.18 + '@types/react': ^17.0.0 || ^18.0.0 react: ^17.0.0 || ^18.0.0 react-dom: ^17.0.0 || ^18.0.0 peerDependenciesMeta: @@ -25086,7 +25089,7 @@ packages: resolution: {integrity: sha512-wub3wxNN+hUp8hzilMlXX3sZrPo75vsy1cXEQpqdTfIFlE9HprP1jlulFiPg5tfPst2OKmygXr2hhmgvAKRrzQ==} engines: {node: '>=12.0.0'} peerDependencies: - '@types/react': 18.0.18 + '@types/react': ^17.0.0 || ^18.0.0 react: ^17.0.0 || ^18.0.0 react-dom: ^17.0.0 || ^18.0.0 peerDependenciesMeta: @@ -25110,7 +25113,7 @@ packages: resolution: {integrity: sha512-ap+juKvt8R8n3cBqd/pGtZydQ4v2I/hgJKnvJRGjpSh3RvsvnDHO4rXov8MHQlH6VqpOekwgilFLGxMZjNTucA==} engines: {node: '>=12.0.0'} peerDependencies: - '@types/react': 18.0.18 + '@types/react': ^17.0.0 || ^18.0.0 react: ^17.0.0 || ^18.0.0 react-dom: ^17.0.0 || ^18.0.0 peerDependenciesMeta: @@ -25138,8 +25141,8 @@ packages: resolution: {integrity: sha512-heL4S+EawrP61xMXBm59QH6HODsu0gxtZi5JtnXF2r+rghzyU/3Uftlt1ij8rmJh+cFdKTQug1L9KkZB5JgpMQ==} engines: {node: '>=12.0.0'} peerDependencies: - '@mui/material': 5.13.0 - '@types/react': 18.0.18 + '@mui/material': ^5.0.0 + '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 react: ^17.0.0 || ^18.0.0 || ^19.0.0 peerDependenciesMeta: '@types/react': @@ -25157,8 +25160,8 @@ packages: peerDependencies: '@emotion/react': ^11.5.0 '@emotion/styled': ^11.3.0 - '@mui/material': 5.13.0 - '@types/react': 18.0.18 + '@mui/material': ^5.0.0 + '@types/react': ^17.0.0 || ^18.0.0 react: ^17.0.0 || ^18.0.0 react-dom: ^17.0.0 || ^18.0.0 peerDependenciesMeta: @@ -25191,8 +25194,8 @@ packages: peerDependencies: '@emotion/react': ^11.5.0 '@emotion/styled': ^11.3.0 - '@mui/material': 5.13.0 - '@types/react': 18.0.18 + '@mui/material': ^5.0.0 + '@types/react': ^17.0.0 || ^18.0.0 react: ^17.0.0 || ^18.0.0 react-dom: ^17.0.0 || ^18.0.0 peerDependenciesMeta: @@ -25225,7 +25228,7 @@ packages: peerDependencies: '@emotion/react': ^11.5.0 '@emotion/styled': ^11.3.0 - '@types/react': 18.0.18 + '@types/react': ^17.0.0 || ^18.0.0 react: ^17.0.0 || ^18.0.0 react-dom: ^17.0.0 || ^18.0.0 peerDependenciesMeta: @@ -25259,7 +25262,7 @@ packages: resolution: {integrity: sha512-12t7NKzvYi819IO5IapW2BcR33wP/KAVrU8d7gLhGHoAmhDxyXlRoKiRij3TOD8+uzk0B6R9wHUNKi4baJcRNg==} engines: {node: '>=12.0.0'} peerDependencies: - '@types/react': 18.0.18 + '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 react: ^17.0.0 || ^18.0.0 || ^19.0.0 peerDependenciesMeta: '@types/react': @@ -25300,7 +25303,7 @@ packages: peerDependencies: '@emotion/react': ^11.5.0 '@emotion/styled': ^11.3.0 - '@types/react': 18.0.18 + '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 react: ^17.0.0 || ^18.0.0 || ^19.0.0 peerDependenciesMeta: '@emotion/react': @@ -25327,7 +25330,7 @@ packages: /@mui/types@7.2.21(@types/react@18.0.18): resolution: {integrity: sha512-6HstngiUxNqLU+/DPqlUJDIPbzUBxIVHb1MmXP0eTWDIROiCR2viugXpEif0PPe2mLqqakPzzRClWAnK+8UJww==} peerDependencies: - '@types/react': 18.0.18 + '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 peerDependenciesMeta: '@types/react': optional: true @@ -25339,7 +25342,7 @@ packages: resolution: {integrity: sha512-wn1QZkRzSmeXD1IguBVvJJHV3s6rxJrfb6YuC9Kk6Noh9f8Fb54nUs5JRkKm+BOerRhj5fLg05Dhx/H3Ofb8Mg==} engines: {node: '>=12.0.0'} peerDependencies: - '@types/react': 18.0.18 + '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 react: ^17.0.0 || ^18.0.0 || ^19.0.0 peerDependenciesMeta: '@types/react': @@ -25359,7 +25362,7 @@ packages: resolution: {integrity: sha512-I0JhinVV4e25hD2dB+R6biPBtpGeFrXf8RwlMPQbr9gUggPmPmNtWKo8Kk2PtBBMlGtdMAgHWe7PqhmucUxU1w==} engines: {node: '>=14.0.0'} peerDependencies: - '@mui/material': 5.13.0 + '@mui/material': ^5.4.1 '@mui/system': ^5.4.1 react: ^17.0.0 || ^18.0.0 react-dom: ^17.0.0 || ^18.0.0 @@ -26584,7 +26587,7 @@ packages: '@emotion/styled': ^11.10.5 '@mui/icons-material': ^5.10.16 '@mui/lab': 5.0.0-alpha.110 - '@mui/material': 5.13.0 + '@mui/material': ^5.10.16 '@mui/system': ^5.10.16 '@mui/utils': ^5.10.16 react: '>=18.0.0' @@ -26620,7 +26623,7 @@ packages: '@emotion/styled': ^11.10.5 '@mui/icons-material': ^5.10.16 '@mui/lab': 5.0.0-alpha.110 - '@mui/material': 5.13.0 + '@mui/material': ^5.10.16 '@mui/system': ^5.10.16 '@mui/utils': ^5.10.16 react: '>=18.0.0' @@ -26656,7 +26659,7 @@ packages: '@emotion/styled': ^11.10.5 '@mui/icons-material': ^5.10.16 '@mui/lab': 5.0.0-alpha.110 - '@mui/material': 5.13.0 + '@mui/material': ^5.10.16 '@mui/system': ^5.10.16 '@mui/utils': ^5.10.16 react: '>=18.0.0' @@ -26860,7 +26863,7 @@ packages: react-refresh: '>=0.8.3 <0.10.0' sockjs-client: ^1.4.0 type-fest: ^0.13.1 - webpack: 5.84.1 + webpack: '>=4.43.0 <6.0.0' webpack-dev-server: 3.x webpack-hot-middleware: 2.x webpack-plugin-serve: 0.x || 1.x @@ -26897,7 +26900,7 @@ packages: react-refresh: '>=0.10.0 <1.0.0' sockjs-client: ^1.4.0 type-fest: '>=0.17.0 <5.0.0' - webpack: 5.84.1 + webpack: '>=4.43.0 <6.0.0' webpack-dev-server: 3.x || 4.x || 5.x webpack-hot-middleware: 2.x webpack-plugin-serve: 0.x || 1.x @@ -26935,7 +26938,7 @@ packages: react-refresh: '>=0.10.0 <1.0.0' sockjs-client: ^1.4.0 type-fest: '>=0.17.0 <5.0.0' - webpack: 5.84.1 + webpack: '>=4.43.0 <6.0.0' webpack-dev-server: 3.x || 4.x || 5.x webpack-hot-middleware: 2.x webpack-plugin-serve: 0.x || 1.x @@ -26973,7 +26976,7 @@ packages: react-refresh: '>=0.10.0 <1.0.0' sockjs-client: ^1.4.0 type-fest: '>=0.17.0 <5.0.0' - webpack: 5.84.1 + webpack: '>=4.43.0 <6.0.0' webpack-dev-server: 3.x || 4.x || 5.x webpack-hot-middleware: 2.x webpack-plugin-serve: 0.x || 1.x @@ -28357,7 +28360,7 @@ packages: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 typescript: '*' - webpack: 5.84.1 + webpack: '*' peerDependenciesMeta: typescript: optional: true @@ -28662,7 +28665,7 @@ packages: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 typescript: '*' - webpack: 5.84.1 + webpack: '*' peerDependenciesMeta: '@storybook/builder-webpack5': optional: true @@ -29043,7 +29046,7 @@ packages: resolution: {integrity: sha512-eVg3BxlOm2P+chijHBTByr90IZVUtgRW56qEOLX7xlww2NBuKrcavBlcmn+HH7GIUktquWkMPtvy6e0W0NgA5w==} peerDependencies: typescript: '>= 3.x' - webpack: 5.84.1 + webpack: '>= 4' dependencies: debug: 4.4.0(supports-color@6.1.0) endent: 2.1.0 @@ -29062,7 +29065,7 @@ packages: resolution: {integrity: sha512-KUqXC3oa9JuQ0kZJLBhVdS4lOneKTOopnNBK4tUAgoxWQ3u/IjzdueZjFr7gyBrXMoU6duutk3RQR9u8ZpYJ4Q==} peerDependencies: typescript: '>= 4.x' - webpack: 5.84.1 + webpack: '>= 4' dependencies: debug: 4.4.0(supports-color@6.1.0) endent: 2.1.0 @@ -30885,7 +30888,7 @@ packages: /@types/react-color@3.0.13(@types/react@18.0.18): resolution: {integrity: sha512-2c/9FZ4ixC5T3JzN0LP5Cke2Mf0MKOP2Eh0NPDPWmuVH3NjPyhEjqNMQpN1Phr5m74egAy+p2lYNAFrX1z9Yrg==} peerDependencies: - '@types/react': 18.0.18 + '@types/react': '*' dependencies: '@types/react': 18.0.18 '@types/reactcss': 1.2.13(@types/react@18.0.18) @@ -30894,7 +30897,7 @@ packages: /@types/react-dom@18.3.5(@types/react@18.0.18): resolution: {integrity: sha512-P4t6saawp+b/dFrUr2cvkVsfvPguwsxtH6dNIYRllMsefqFzkZk5UIjzyDOv5g1dXIPdG4Sp1yCR4Z6RCUsG/Q==} peerDependencies: - '@types/react': 18.0.18 + '@types/react': ^18.0.0 dependencies: '@types/react': 18.0.18 dev: true @@ -30931,7 +30934,7 @@ packages: /@types/react-transition-group@4.4.12(@types/react@18.0.18): resolution: {integrity: sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w==} peerDependencies: - '@types/react': 18.0.18 + '@types/react': '*' dependencies: '@types/react': 18.0.18 dev: false @@ -30946,7 +30949,7 @@ packages: /@types/reactcss@1.2.13(@types/react@18.0.18): resolution: {integrity: sha512-gi3S+aUi6kpkF5vdhUsnkwbiSEIU/BEJyD7kBy2SudWBUuKmJk8AQKE0OVcQQeEy40Azh0lV6uynxlikYIJuwg==} peerDependencies: - '@types/react': 18.0.18 + '@types/react': '*' dependencies: '@types/react': 18.0.18 dev: true @@ -31526,7 +31529,7 @@ packages: /@webpack-cli/configtest@1.2.0(webpack-cli@4.10.0)(webpack@5.84.1): resolution: {integrity: sha512-4FB8Tj6xyVkyqjj1OaTqCjXYULB9FMkqQ8yGrZjRDrYh0nOE+7Lhs45WioWQQMV+ceFlE368Ukhe6xdvJM9Egg==} peerDependencies: - webpack: 5.84.1 + webpack: 4.x.x || 5.x.x webpack-cli: 4.x.x dependencies: webpack: 5.84.1(@swc/core@1.3.99)(esbuild@0.18.20)(webpack-cli@4.10.0) @@ -31556,7 +31559,7 @@ packages: resolution: {integrity: sha512-LonryJP+FxQQHsjGBi6W786TQB1Oym+agTpY0c+Kj8alnIw+DLUJb6SI8Y1GHGhLCH1yPRrucjObUmxNICQ1pg==} engines: {node: '>= 6.9.0 || >= 8.9.0'} peerDependencies: - webpack: 5.84.1 + webpack: ^3.0.0 || ^4.0.0 dependencies: ajv: 6.12.6 ajv-keywords: 3.5.2(ajv@6.12.6) @@ -32427,7 +32430,7 @@ packages: engines: {node: '>= 8.9'} peerDependencies: '@babel/core': ^7.0.0 - webpack: 5.84.1 + webpack: '>=2' dependencies: '@babel/core': 7.26.0 find-cache-dir: 3.3.2 @@ -32441,7 +32444,7 @@ packages: engines: {node: '>= 14.15.0'} peerDependencies: '@babel/core': ^7.12.0 - webpack: 5.84.1 + webpack: '>=5' dependencies: '@babel/core': 7.26.0 find-cache-dir: 4.0.0 @@ -33774,7 +33777,7 @@ packages: resolution: {integrity: sha512-9DKNW6ILLjx+bNBoviHDgLx6swBhWWH9ApClC9sTH2NoFfQM47BapQfovCm9zjD9v1uZwInF5a925FB9ErGQeQ==} engines: {node: '>= 10.13.0'} peerDependencies: - webpack: 5.84.1 + webpack: ^5.1.0 dependencies: schema-utils: 3.3.0 serialize-javascript: 5.0.1 @@ -33999,7 +34002,7 @@ packages: resolution: {integrity: sha512-xFVltahqlsRcyyJqQbDY6EYTtyQZF9rf+JPjwHObLdPFMEISqkFkr7mFoVOC6BfYS/dNThyoQKvziugm+OnwBg==} engines: {node: '>= 12.20.0'} peerDependencies: - webpack: 5.84.1 + webpack: ^5.1.0 dependencies: fast-glob: 3.3.3 glob-parent: 6.0.2 @@ -34014,7 +34017,7 @@ packages: resolution: {integrity: sha512-SNwdBeHyII+rWvee/bTnAYyO8vfVdcSTud4EIb6jcZ8inLeWucJE0DnxXQBjlQ5zlteuuvooGQy3LIyGxhvlOA==} engines: {node: '>= 18.12.0'} peerDependencies: - webpack: 5.84.1 + webpack: ^5.1.0 dependencies: fast-glob: 3.3.3 glob-parent: 6.0.2 @@ -34231,7 +34234,7 @@ packages: resolution: {integrity: sha512-+ZHAZm/yqvJ2kDtPne3uX0C+Vr3Zn5jFn2N4HywtS5ujwvsVkyg0VArEXpl3BgczDA8anieki1FIzhchX4yrDw==} engines: {node: '>= 6.9.0 <7.0.0 || >= 8.9.0'} peerDependencies: - webpack: 5.84.1 + webpack: ^4.0.0 dependencies: babel-code-frame: 6.26.0 css-selector-tokenizer: 0.7.3 @@ -34252,7 +34255,7 @@ packages: resolution: {integrity: sha512-M5lSukoWi1If8dhQAUCvj4H8vUt3vOnwbQBH9DdTm/s4Ym2B/3dPMtYZeJmq7Q3S3Pa+I94DcZ7pc9bP14cWIQ==} engines: {node: '>= 8.9.0'} peerDependencies: - webpack: 5.84.1 + webpack: ^4.0.0 || ^5.0.0 dependencies: camelcase: 5.3.1 cssesc: 3.0.0 @@ -34274,7 +34277,7 @@ packages: resolution: {integrity: sha512-Q7mOvpBNBG7YrVGMxRxcBJZFL75o+cH2abNASdibkj/fffYD8qWbInZrD0S9ccI6vZclF3DsHE7njGlLtaHbhg==} engines: {node: '>= 10.13.0'} peerDependencies: - webpack: 5.84.1 + webpack: ^4.27.0 || ^5.0.0 dependencies: icss-utils: 5.1.0(postcss@8.5.1) loader-utils: 2.0.4 @@ -34294,7 +34297,7 @@ packages: engines: {node: '>= 12.13.0'} peerDependencies: '@rspack/core': 0.x || 1.x - webpack: 5.84.1 + webpack: ^5.0.0 peerDependenciesMeta: '@rspack/core': optional: true @@ -34322,7 +34325,7 @@ packages: csso: '*' esbuild: '*' lightningcss: '*' - webpack: 5.84.1 + webpack: ^5.0.0 peerDependenciesMeta: '@parcel/css': optional: true @@ -36084,7 +36087,7 @@ packages: engines: {node: '>= 10.13.0'} peerDependencies: eslint: ^7.0.0 || ^8.0.0 - webpack: 5.84.1 + webpack: ^4.0.0 || ^5.0.0 dependencies: '@types/eslint': 7.29.0 arrify: 2.0.1 @@ -36101,7 +36104,7 @@ packages: engines: {node: '>= 12.13.0'} peerDependencies: eslint: ^7.0.0 || ^8.0.0 - webpack: 5.84.1 + webpack: ^5.0.0 dependencies: '@types/eslint': 8.56.12 eslint: 8.46.0 @@ -36505,7 +36508,7 @@ packages: resolution: {integrity: sha512-Hypkn9jUTnFr0DpekNam53X47tXn3ucY08BQumv7kdGgeVUBLq3DJHJTi6HNxv4jl9W+Skxjz9+RnK0sJyqqjA==} engines: {node: '>= 6.9.0 || >= 8.9.0'} peerDependencies: - webpack: 5.84.1 + webpack: ^3.0.0 || ^4.0.0 dependencies: async: 2.6.4 loader-utils: 1.4.2 @@ -36647,7 +36650,7 @@ packages: resolution: {integrity: sha512-YCsBfd1ZGCyonOKLxPiKPdu+8ld9HAaMEvJewzz+b2eTF7uL5Zm/HdBF6FjCrpCMRq25Mi0U1gl4pwn2TlH7hQ==} engines: {node: '>= 6.9.0 < 7.0.0 || >= 8.9.0'} peerDependencies: - webpack: 5.84.1 + webpack: ^2.0.0 || ^3.0.0 || ^4.0.0 dependencies: loader-utils: 1.4.2 schema-utils: 1.0.0 @@ -36658,7 +36661,7 @@ packages: resolution: {integrity: sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==} engines: {node: '>= 10.13.0'} peerDependencies: - webpack: 5.84.1 + webpack: ^4.0.0 || ^5.0.0 dependencies: loader-utils: 2.0.4 schema-utils: 3.3.0 @@ -36937,7 +36940,7 @@ packages: eslint: '>= 6' typescript: '>= 2.7' vue-template-compiler: '*' - webpack: 5.84.1 + webpack: '>= 4' peerDependenciesMeta: eslint: optional: true @@ -36965,7 +36968,7 @@ packages: eslint: '>= 6' typescript: '>= 2.7' vue-template-compiler: '*' - webpack: 5.84.1 + webpack: '>= 4' peerDependenciesMeta: eslint: optional: true @@ -36996,7 +36999,7 @@ packages: eslint: '>= 6' typescript: '>= 2.7' vue-template-compiler: '*' - webpack: 5.84.1 + webpack: '>= 4' peerDependenciesMeta: eslint: optional: true @@ -37027,7 +37030,7 @@ packages: peerDependencies: typescript: '>3.6.0' vue-template-compiler: '*' - webpack: 5.84.1 + webpack: ^5.11.0 peerDependenciesMeta: vue-template-compiler: optional: true @@ -37053,7 +37056,7 @@ packages: engines: {node: '>=12.13.0', yarn: '>=1.0.0'} peerDependencies: typescript: '>3.6.0' - webpack: 5.84.1 + webpack: ^5.11.0 dependencies: '@babel/code-frame': 7.26.2 chalk: 4.1.2 @@ -38104,7 +38107,7 @@ packages: resolution: {integrity: sha512-q5oYdzjKUIPQVjOosjgvCHQOv9Ett9CYYHlgvJeXG0qQvdSojnBq4vAdQBwn1+yGveAwHCoe/rMR86ozX3+c2A==} engines: {node: '>=6.9'} peerDependencies: - webpack: 5.84.1 + webpack: ^4.0.0 || ^5.0.0 dependencies: '@types/html-minifier-terser': 5.1.2 '@types/tapable': 1.0.12 @@ -38123,7 +38126,7 @@ packages: engines: {node: '>=10.13.0'} peerDependencies: '@rspack/core': 0.x || 1.x - webpack: 5.84.1 + webpack: ^5.20.0 peerDependenciesMeta: '@rspack/core': optional: true @@ -40559,7 +40562,7 @@ packages: resolution: {integrity: sha512-PJaNiSeZlZStdyLtJo/QOOC7uHRW9qvc//7F8M0ZH1huPSvmX5kR2qrq2Tn1ODYLi128bTkKepqtgYmtEOkPzQ==} engines: {node: '>= 14.15.0'} peerDependencies: - webpack: 5.84.1 + webpack: ^5.1.0 dependencies: schema-utils: 4.3.0 webpack: 5.84.1(@swc/core@1.3.99)(esbuild@0.18.20)(webpack-cli@4.10.0) @@ -40569,7 +40572,7 @@ packages: resolution: {integrity: sha512-GT/SZolN2p405EMGjMTBvAVi2+y035p1tSOuLpWbp5QTMl080OHx4DEGXfUH6vbnGw5Z/QKfBe+KpP9Dj0qLmA==} engines: {node: '>= 18.12.0'} peerDependencies: - webpack: 5.84.1 + webpack: ^5.1.0 dependencies: schema-utils: 4.3.0 webpack: 5.84.1(@swc/core@1.3.99)(esbuild@0.18.20)(webpack-cli@4.10.0) @@ -40825,7 +40828,7 @@ packages: engines: {node: '>= 14.15.0'} peerDependencies: less: ^3.5.0 || ^4.0.0 - webpack: 5.84.1 + webpack: ^5.0.0 dependencies: klona: 2.0.6 less: 4.1.3 @@ -40837,7 +40840,7 @@ packages: engines: {node: '>= 4.8.0'} peerDependencies: less: ^2.3.1 || ^3.0.0 - webpack: 5.84.1 + webpack: ^2.0.0 || ^3.0.0 || ^4.0.0 dependencies: clone: 2.1.2 less: 3.13.1 @@ -41920,7 +41923,7 @@ packages: resolution: {integrity: sha512-dqBanNfktnp2hwL2YguV9Jh91PFX7gu7nRLs4TGsbAfAG6WOtlynFRYzwDwmmeSb5uIwHo9nx1ta0f7vAZVp2w==} engines: {node: '>= 6.9.0 <7.0.0 || >= 8.9.0'} peerDependencies: - webpack: 5.84.1 + webpack: ^4.4.0 dependencies: loader-utils: 1.4.2 schema-utils: 1.0.0 @@ -41932,7 +41935,7 @@ packages: resolution: {integrity: sha512-euWmddf0sk9Nv1O0gfeeUAvAkoSlWncNLF77C0TP2+WoPvy8mAHKOzMajcCz2dzvyt3CNgxb1obIEVFIRxaipg==} engines: {node: '>= 12.13.0'} peerDependencies: - webpack: 5.84.1 + webpack: ^5.0.0 dependencies: schema-utils: 4.3.0 webpack: 5.84.1(@swc/core@1.3.99)(esbuild@0.18.20)(webpack-cli@4.10.0) @@ -43864,7 +43867,7 @@ packages: engines: {node: '>= 10.13.0'} peerDependencies: postcss: ^7.0.0 || ^8.0.1 - webpack: 5.84.1 + webpack: ^4.0.0 || ^5.0.0 dependencies: cosmiconfig: 7.1.0 klona: 2.0.6 @@ -43880,7 +43883,7 @@ packages: engines: {node: '>= 12.13.0'} peerDependencies: postcss: ^7.0.0 || ^8.0.1 - webpack: 5.84.1 + webpack: ^5.0.0 dependencies: cosmiconfig: 7.1.0 klona: 2.0.6 @@ -44863,7 +44866,7 @@ packages: resolution: {integrity: sha512-ZnScIV3ag9A4wPX/ZayxL/jZH+euYb6FcUinPcgiQW0+UBtEv0O6Q3lGd3cqJ+GHH+rksEv3Pj99oxJ3u3VIKA==} engines: {node: '>= 10.13.0'} peerDependencies: - webpack: 5.84.1 + webpack: ^4.0.0 || ^5.0.0 dependencies: loader-utils: 2.0.4 schema-utils: 3.3.0 @@ -45171,7 +45174,7 @@ packages: resolution: {integrity: sha512-ZlqCfVRqDJmMXTulUGic4lN7Ic1SXgHAFw7y/Jb7t25GBgTR0fYAJ8uY4mrpxjRyWGWmqw77qJQGnYbzCvBU7g==} engines: {node: '>= 6'} peerDependencies: - '@types/react': 18.0.18 + '@types/react': ^15.0.0 || ^16.0.0 || ^17.0.0 react: ^15.0.0 || ^16.0.0 || ^17.0.0 react-dom: ^15.0.0 || ^16.0.0 || ^17.0.0 peerDependenciesMeta: @@ -45221,7 +45224,7 @@ packages: /react-innertext@1.1.5(@types/react@18.0.18)(react@18.3.1): resolution: {integrity: sha512-PWAqdqhxhHIv80dT9znP2KvS+hfkbRovFp4zFYHFFlOoQLRiawIic81gKb3U1wEyJZgMwgs3JoLtwryASRWP3Q==} peerDependencies: - '@types/react': 18.0.18 + '@types/react': '>=0.0.0 <=99' react: '>=0.0.0 <=99' dependencies: '@types/react': 18.0.18 @@ -45286,7 +45289,7 @@ packages: /react-markdown@9.0.3(@types/react@18.0.18)(react@18.3.1): resolution: {integrity: sha512-Yk7Z94dbgYTOrdk41Z74GoKA7rThnsbbqBTRYuxoe08qvfQ9tJVhmAKw6BJS/ZORG7kTy/s1QvYzSuaoBA1qfw==} peerDependencies: - '@types/react': 18.0.18 + '@types/react': '>=18' react: '>=18' dependencies: '@types/hast': 3.0.4 @@ -46528,7 +46531,7 @@ packages: node-sass: ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 sass: ^1.3.0 sass-embedded: '*' - webpack: 5.84.1 + webpack: ^5.0.0 peerDependenciesMeta: fibers: optional: true @@ -47151,7 +47154,7 @@ packages: resolution: {integrity: sha512-BokxPoLjyl3iOrgkWaakaxqnelAJSS+0V+De0kKIq6lyWrXuiPgYTGp6z3iHmqljKAaLXwZa+ctD8GccRJeVvg==} engines: {node: '>= 12.13.0'} peerDependencies: - webpack: 5.84.1 + webpack: ^5.0.0 dependencies: abab: 2.0.6 iconv-lite: 0.6.3 @@ -47705,7 +47708,7 @@ packages: resolution: {integrity: sha512-V7TCORko8rs9rIqkSrlMfkqA63DfoGBBJmK1kKGCcSi+BWb4cqz0SRsnp4l6rU5iwOEd0/2ePv68SV22VXon4Q==} engines: {node: '>= 8.9.0'} peerDependencies: - webpack: 5.84.1 + webpack: ^4.0.0 || ^5.0.0 dependencies: loader-utils: 2.0.4 schema-utils: 2.7.1 @@ -47716,7 +47719,7 @@ packages: resolution: {integrity: sha512-Z0gYUJmzZ6ZdRUqpg1r8GsaFKypE+3xAzuFeMuoHgjc9KZv3wMyCRjQIWEbhoFSq7+7yoHXySDJyyWQaPajeiQ==} engines: {node: '>= 10.13.0'} peerDependencies: - webpack: 5.84.1 + webpack: ^4.0.0 || ^5.0.0 dependencies: loader-utils: 2.0.4 schema-utils: 3.3.0 @@ -47727,7 +47730,7 @@ packages: resolution: {integrity: sha512-0WqXzrsMTyb8yjZJHDqwmnwRJvhALK9LfRtRc6B4UTWe8AijYLZYZ9thuJTZc2VfQWINADW/j+LiJnfy2RoC1w==} engines: {node: '>= 12.13.0'} peerDependencies: - webpack: 5.84.1 + webpack: ^5.0.0 dependencies: webpack: 5.84.1(@swc/core@1.3.99)(esbuild@0.18.20)(webpack-cli@4.10.0) dev: true @@ -47818,7 +47821,7 @@ packages: engines: {node: '>= 14.15.0'} peerDependencies: stylus: '>=0.52.4' - webpack: 5.84.1 + webpack: ^5.0.0 dependencies: fast-glob: 3.3.3 normalize-path: 3.0.0 @@ -47938,7 +47941,7 @@ packages: resolution: {integrity: sha512-9Zi9UP2YmDpgmQVbyOPJClY0dwf58JDyDMQ7uRc4krmc72twNI2fvlBWHLqVekBpPc7h5NJkGVT1zNDxFrqhvg==} peerDependencies: '@swc/core': ^1.2.147 - webpack: 5.84.1 + webpack: '>=2' dependencies: '@swc/core': 1.3.99(@swc/helpers@0.5.9) '@swc/counter': 0.1.3 @@ -48083,7 +48086,7 @@ packages: resolution: {integrity: sha512-jTgXh40RnvOrLQNgIkwEKnQ8rmHjHK4u+6UBEi+W+FPmvb+uo+chJXntKe7/3lW5mNysgSWD60KyesnhW8D6MQ==} engines: {node: '>= 10.13.0'} peerDependencies: - webpack: 5.84.1 + webpack: ^4.0.0 || ^5.0.0 dependencies: cacache: 15.3.0 find-cache-dir: 3.3.2 @@ -48106,7 +48109,7 @@ packages: '@swc/core': '*' esbuild: '*' uglify-js: '*' - webpack: 5.84.1 + webpack: ^5.1.0 peerDependenciesMeta: '@swc/core': optional: true @@ -48165,7 +48168,7 @@ packages: resolution: {integrity: sha512-wNrVKH2Lcf8ZrWxDF/khdlLlsTMczdcwPA9VEK4c2exlEPynYWxi9op3nPTo5lAnDIkE0rQEB3VBP+4Zncc9Hg==} engines: {node: '>= 6.9.0 <7.0.0 || >= 8.9.0'} peerDependencies: - webpack: 5.84.1 + webpack: ^2.0.0 || ^3.0.0 || ^4.0.0 dependencies: loader-runner: 2.4.0 loader-utils: 1.4.2 @@ -48519,7 +48522,7 @@ packages: engines: {node: '>=12.0.0'} peerDependencies: typescript: '*' - webpack: 5.84.1 + webpack: ^5.0.0 dependencies: chalk: 4.1.2 enhanced-resolve: 5.18.0 @@ -49089,7 +49092,7 @@ packages: engines: {node: '>= 10.13.0'} peerDependencies: file-loader: '*' - webpack: 5.84.1 + webpack: ^4.0.0 || ^5.0.0 peerDependenciesMeta: file-loader: optional: true @@ -49106,7 +49109,7 @@ packages: engines: {node: '>= 10.13.0'} peerDependencies: file-loader: '*' - webpack: 5.84.1 + webpack: ^4.0.0 || ^5.0.0 peerDependenciesMeta: file-loader: optional: true @@ -49430,7 +49433,7 @@ packages: peerDependencies: '@webpack-cli/generators': '*' '@webpack-cli/migrate': '*' - webpack: 5.84.1 + webpack: 4.x.x || 5.x.x webpack-bundle-analyzer: '*' webpack-dev-server: '*' peerDependenciesMeta: @@ -49463,7 +49466,7 @@ packages: resolution: {integrity: sha512-djelc/zGiz9nZj/U7PTBi2ViorGJXEWo/3ltkPbDyxCXhhEXkW0ce99falaok4TPj+AsxLiXJR0EBOb0zh9fKQ==} engines: {node: '>= 6'} peerDependencies: - webpack: 5.84.1 + webpack: ^4.0.0 || ^5.0.0 dependencies: memory-fs: 0.4.1 mime: 2.6.0 @@ -49476,7 +49479,7 @@ packages: resolution: {integrity: sha512-PjwyVY95/bhBh6VUqt6z4THplYcsvQ8YNNBTBM873xLVmw8FLeALn0qurHbs9EmcfhzQis/eoqypSnZeuUz26w==} engines: {node: '>= v10.23.3'} peerDependencies: - webpack: 5.84.1 + webpack: ^4.0.0 || ^5.0.0 dependencies: colorette: 1.4.0 mem: 8.1.1 @@ -49491,7 +49494,7 @@ packages: resolution: {integrity: sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q==} engines: {node: '>= 12.13.0'} peerDependencies: - webpack: 5.84.1 + webpack: ^4.0.0 || ^5.0.0 dependencies: colorette: 2.0.20 memfs: 3.5.3 @@ -49505,7 +49508,7 @@ packages: resolution: {integrity: sha512-A4ChP0Qj8oGociTs6UdlRUGANIGrCDL3y+pmQMc+dSsraXHCatFpmMey4mYELA+juqwUqwQsUgJJISXl1KWmiw==} engines: {node: '>= 14.15.0'} peerDependencies: - webpack: 5.84.1 + webpack: ^5.0.0 peerDependenciesMeta: webpack: optional: true @@ -49523,7 +49526,7 @@ packages: engines: {node: '>= 6.11.5'} hasBin: true peerDependencies: - webpack: 5.84.1 + webpack: ^4.0.0 || ^5.0.0 webpack-cli: '*' peerDependenciesMeta: webpack-cli: @@ -49573,7 +49576,7 @@ packages: engines: {node: '>= 12.13.0'} hasBin: true peerDependencies: - webpack: 5.84.1 + webpack: ^4.37.0 || ^5.0.0 webpack-cli: '*' peerDependenciesMeta: webpack: @@ -49624,7 +49627,7 @@ packages: resolution: {integrity: sha512-Ez6ytc9IseDMLPo0qCuNNYzgtUl8NovOqjIq4uAU8LTD4uoa1w1KpZyyzFtLTEMZpkkOkLfL9eN+KGYdk1Qtwg==} engines: {node: '>= 4.3 < 5.0.0 || >= 5.10'} peerDependencies: - webpack: 5.84.1 + webpack: ^2.0.0 || ^3.0.0 || ^4.0.0 dependencies: webpack: 5.84.1(@swc/core@1.3.99)(esbuild@0.18.20)(webpack-cli@4.10.0) dev: false @@ -49681,7 +49684,7 @@ packages: engines: {node: '>= 12'} peerDependencies: html-webpack-plugin: '>= 5.0.0-beta.1 < 6' - webpack: 5.84.1 + webpack: ^5.12.0 peerDependenciesMeta: html-webpack-plugin: optional: true @@ -49898,7 +49901,7 @@ packages: resolution: {integrity: sha512-tnvNp4K3KQOpfRnD20m8xltE3eWh89Ye+5oj7wXEEHKac1P4oZ6p9oTj8/8ExqoSBnk9nu5Pr4nKfQ1hn2APJw==} engines: {node: '>= 6.9.0 || >= 8.9.0'} peerDependencies: - webpack: 5.84.1 + webpack: ^3.0.0 || ^4.0.0-alpha.0 || ^4.0.0 dependencies: loader-utils: 1.4.2 schema-utils: 0.4.7 @@ -50213,7 +50216,7 @@ packages: resolution: {integrity: sha512-ibr/n1hBzLLj5Y+yUcU7dYw8p6WnIVzdJbnX+1YpaScvZVF2ziugqHs+LAmHw4lWO9c/zRj+K1ncgWDQuthEdQ==} engines: {node: '>=12.7.0'} peerDependencies: - '@types/react': 18.0.18 + '@types/react': '>=16.8' immer: '>=9.0.6' react: '>=16.8' peerDependenciesMeta: