@rancher/shell 3.0.12-rc.3 → 3.0.12-rc.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/styles/global/_layout.scss +4 -0
- package/assets/translations/en-us.yaml +144 -41
- package/assets/translations/zh-hans.yaml +1 -7
- package/chart/monitoring/ClusterSelector.vue +0 -21
- package/chart/monitoring/prometheus/index.vue +6 -3
- package/components/CruResource.vue +161 -14
- package/components/ExplorerMembers.vue +8 -4
- package/components/ExplorerProjectsNamespaces.vue +10 -6
- package/components/GrowlManager.vue +4 -0
- package/components/MgmtNodeList.vue +184 -0
- package/components/Resource/Detail/Card/StateCard/__tests__/composables.test.ts +90 -1
- package/components/Resource/Detail/Card/StateCard/composables.ts +57 -87
- package/components/Resource/Detail/Card/StatusCard/__tests__/StatusCard.test.ts +61 -0
- package/components/Resource/Detail/Card/StatusCard/index.vue +61 -15
- package/components/Resource/Detail/Metadata/IdentifyingInformation/index.vue +2 -0
- package/components/Resource/Detail/Metadata/KeyValue.vue +5 -2
- package/components/Resource/Detail/Metadata/KeyValueRow.vue +2 -6
- package/components/ResourceDetail/index.vue +1 -1
- package/components/ResourceList/Masthead.vue +7 -1
- package/components/ResourceList/index.vue +82 -1
- package/components/RichTranslation.vue +5 -2
- package/components/Setting.vue +1 -0
- package/components/SubtleLink.vue +31 -6
- package/components/Tabbed/Tab.vue +29 -3
- package/components/Tabbed/index.vue +25 -3
- package/components/TableOfContents/TableOfContents.vue +109 -0
- package/components/TableOfContents/composables.ts +258 -0
- package/components/Window/ContainerShell.vue +21 -11
- package/components/Window/__tests__/ContainerShell.test.ts +107 -37
- package/components/Wizard.vue +9 -4
- package/components/fleet/AppCoChartGrid.vue +401 -0
- package/components/fleet/AppCoEmptyState.vue +127 -0
- package/components/fleet/AppCoPageHeader.vue +119 -0
- package/components/fleet/AppCoVersionSelect.vue +70 -0
- package/components/fleet/FleetClusterTargets/ClusterSelectionFields.vue +217 -0
- package/components/fleet/FleetClusterTargets/TargetsList.vue +123 -35
- package/components/fleet/FleetClusterTargets/index.vue +189 -146
- package/components/fleet/FleetIntro.vue +7 -3
- package/components/fleet/FleetNoWorkspaces.vue +7 -3
- package/components/fleet/FleetSecretSelector.vue +5 -3
- package/components/fleet/FleetValuesFrom.vue +8 -2
- package/components/fleet/GitRepoTargetTab.vue +0 -2
- package/components/fleet/HelmOpAdvancedTab.vue +19 -53
- package/components/fleet/HelmOpAppCoConfigTab.vue +593 -0
- package/components/fleet/HelmOpAppCoResourcesSection.vue +162 -0
- package/components/fleet/HelmOpResourcesSection.vue +82 -0
- package/components/fleet/HelmOpTargetOptionsSection.vue +89 -0
- package/components/fleet/HelmOpTargetTab.vue +64 -60
- package/components/fleet/HelmOpValuesTab.vue +129 -105
- package/components/fleet/__tests__/AppCoEmptyState.test.ts +71 -0
- package/components/fleet/__tests__/AppCoVersionSelect.test.ts +36 -0
- package/components/fleet/__tests__/ClusterSelectionFields.test.ts +62 -0
- package/components/fleet/__tests__/FleetClusterTargets.test.ts +253 -0
- package/components/fleet/__tests__/FleetSecretSelector.test.ts +16 -0
- package/components/fleet/__tests__/FleetValuesFrom.test.ts +44 -0
- package/components/fleet/__tests__/HelmOpAppCoConfigTab.test.ts +59 -0
- package/components/fleet/__tests__/HelmOpAppCoResourcesSection.test.ts +62 -0
- package/components/fleet/__tests__/HelmOpResourcesSection.test.ts +43 -0
- package/components/fleet/__tests__/HelmOpTargetOptionsSection.test.ts +34 -0
- package/components/fleet/__tests__/HelmOpValuesTab.test.ts +39 -0
- package/components/fleet/__tests__/__snapshots__/AppCoEmptyState.test.ts.snap +97 -0
- package/components/fleet/__tests__/__snapshots__/AppCoVersionSelect.test.ts.snap +30 -0
- package/components/fleet/__tests__/__snapshots__/ClusterSelectionFields.test.ts.snap +209 -0
- package/components/fleet/__tests__/__snapshots__/HelmOpTargetOptionsSection.test.ts.snap +140 -0
- package/components/fleet/dashboard/Empty.vue +8 -4
- package/components/fleet/dashboard/ResourceCard.vue +28 -0
- package/components/fleet/dashboard/ResourceDetails.vue +28 -0
- package/components/fleet/dashboard/__tests__/ResourceCard.test.ts +87 -0
- package/components/form/ArrayList.vue +61 -4
- package/components/form/KeyValue.vue +23 -2
- package/components/form/LabeledSelect.vue +39 -1
- package/components/form/Labels.vue +22 -3
- package/components/form/NameNsDescription.vue +13 -5
- package/components/form/ResourceTabs/index.vue +1 -0
- package/components/form/__tests__/NameNsDescription.test.ts +75 -0
- package/components/formatter/InternalExternalIP.vue +10 -4
- package/components/formatter/ServiceTargets.vue +26 -7
- package/components/formatter/__tests__/InternalExternalIP.test.ts +132 -0
- package/components/formatter/__tests__/ServiceTargets.test.ts +412 -0
- package/components/nav/Header.vue +4 -0
- package/components/nav/TopLevelMenu.vue +7 -2
- package/components/nav/__tests__/Header.test.ts +15 -0
- package/components/nav/__tests__/TopLevelMenu.test.ts +120 -2
- package/components/templates/default.vue +9 -4
- package/components/templates/home.vue +9 -4
- package/components/templates/plain.vue +9 -4
- package/composables/useHelmOpResources.test.ts +56 -0
- package/composables/useHelmOpResources.ts +32 -0
- package/composables/useStateColor.test.ts +325 -0
- package/composables/useStateColor.ts +128 -0
- package/config/home-links.js +1 -1
- package/config/labels-annotations.js +1 -0
- package/config/product/explorer.js +17 -4
- package/config/product/manager.js +2 -0
- package/config/router/index.js +16 -0
- package/config/router/navigation-guards/__tests__/authentication.test.ts +130 -0
- package/config/router/navigation-guards/authentication.js +10 -4
- package/config/router/routes.js +20 -6
- package/config/settings.ts +0 -2
- package/config/table-headers.js +3 -4
- package/config/types.js +9 -0
- package/core/plugin-products-base.ts +3 -3
- package/core/plugin-types.ts +83 -30
- package/core/plugin.ts +3 -0
- package/core/types-provisioning.ts +34 -1
- package/core/types.ts +15 -2
- package/detail/__tests__/provisioning.cattle.io.cluster.test.ts +114 -0
- package/detail/__tests__/workload.test.ts +3 -152
- package/detail/catalog.cattle.io.clusterrepo.vue +1 -1
- package/detail/provisioning.cattle.io.cluster.vue +30 -4
- package/detail/workload/index.vue +12 -55
- package/edit/__tests__/catalog.cattle.io.clusterrepo.test.ts +248 -0
- package/edit/__tests__/fleet.cattle.io.helmop.test.ts +105 -0
- package/edit/auditlog.cattle.io.auditpolicy/__tests__/__snapshots__/General.test.ts.snap +6 -0
- package/edit/auditlog.cattle.io.auditpolicy/__tests__/__snapshots__/index.test.ts.snap +1 -0
- package/edit/auth/__tests__/azuread.test.ts +34 -9
- package/edit/auth/__tests__/github.test.ts +234 -0
- package/edit/auth/__tests__/oidc.test.ts +26 -6
- package/edit/auth/__tests__/saml.test.ts +196 -0
- package/edit/auth/azuread.vue +128 -95
- package/edit/auth/github.vue +72 -13
- package/edit/auth/ldap/__tests__/index.test.ts +206 -0
- package/edit/auth/ldap/config.vue +8 -0
- package/edit/auth/ldap/index.vue +75 -1
- package/edit/auth/oidc.vue +119 -73
- package/edit/auth/saml.vue +76 -12
- package/edit/catalog.cattle.io.clusterrepo.vue +140 -32
- package/edit/fleet.cattle.io.helmop.vue +491 -136
- package/edit/management.cattle.io.user.vue +5 -2
- package/edit/provisioning.cattle.io.cluster/rke2.vue +84 -10
- package/edit/provisioning.cattle.io.cluster/tabs/MachinePool.vue +11 -0
- package/list/group.principal.vue +5 -4
- package/list/harvesterhci.io.management.cluster.vue +8 -9
- package/list/management.cattle.io.user.vue +12 -9
- package/list/provisioning.cattle.io.cluster.vue +16 -10
- package/mixins/__tests__/auth-config.test.ts +90 -0
- package/mixins/__tests__/chart.test.ts +94 -0
- package/mixins/__tests__/resource-fetch-api-pagination.test.ts +48 -0
- package/mixins/auth-config.js +7 -0
- package/mixins/chart.js +11 -2
- package/mixins/child-hook.js +12 -6
- package/mixins/create-edit-view/impl.js +5 -3
- package/mixins/resource-fetch-api-pagination.js +21 -1
- package/models/__tests__/catalog.cattle.io.clusterrepo.test.ts +57 -0
- package/models/__tests__/compliance.cattle.io.clusterscan.test.ts +144 -0
- package/models/__tests__/fleet-application.test.ts +175 -0
- package/models/__tests__/fleet.cattle.io.bundle.test.ts +169 -0
- package/models/__tests__/fleet.cattle.io.helmop.test.ts +84 -0
- package/models/__tests__/management.cattle.io.node.ts +22 -0
- package/models/__tests__/namespace.test.ts +36 -0
- package/models/__tests__/provisioning.cattle.io.cluster.test.ts +49 -0
- package/models/__tests__/workload.test.ts +401 -26
- package/models/catalog.cattle.io.clusterrepo.js +28 -4
- package/models/compliance.cattle.io.clusterscan.js +39 -4
- package/models/fleet-application.js +4 -0
- package/models/fleet.cattle.io.helmop.js +20 -1
- package/models/management.cattle.io.cluster.js +18 -2
- package/models/management.cattle.io.node.js +44 -3
- package/models/namespace.js +1 -1
- package/models/pod.js +33 -1
- package/models/provisioning.cattle.io.cluster.js +5 -5
- package/models/workload.js +108 -13
- package/models/workload.service.js +5 -0
- package/package.json +14 -13
- package/pages/about.vue +5 -6
- package/pages/auth/login.vue +0 -35
- package/pages/auth/setup.vue +11 -0
- package/pages/c/_cluster/apps/charts/AppChartCardFooter.vue +2 -2
- package/pages/c/_cluster/apps/charts/AppChartCardSubHeader.vue +10 -1
- package/pages/c/_cluster/apps/charts/__tests__/index.test.ts +93 -0
- package/pages/c/_cluster/apps/charts/chart.vue +2 -1
- package/pages/c/_cluster/apps/charts/index.vue +48 -10
- package/pages/c/_cluster/apps/charts/install.vue +122 -116
- package/pages/c/_cluster/auth/roles/index.vue +5 -4
- package/pages/c/_cluster/explorer/workload-dashboard/ByNamespaceSection.vue +31 -0
- package/pages/c/_cluster/explorer/workload-dashboard/ByStateSection.vue +138 -0
- package/pages/c/_cluster/explorer/workload-dashboard/ByTypeSection.vue +30 -0
- package/pages/c/_cluster/explorer/workload-dashboard/WorkloadCard.vue +155 -0
- package/pages/c/_cluster/explorer/workload-dashboard/WorkloadNamespaceCard.vue +142 -0
- package/pages/c/_cluster/explorer/workload-dashboard/WorkloadTypeCard.vue +159 -0
- package/pages/c/_cluster/explorer/workload-dashboard/__tests__/composable.test.ts +561 -0
- package/pages/c/_cluster/explorer/workload-dashboard/composable.ts +440 -0
- package/pages/c/_cluster/explorer/workload-dashboard/index.vue +187 -0
- package/pages/c/_cluster/explorer/workload-dashboard/types.ts +80 -0
- package/pages/c/_cluster/fleet/application/create.vue +187 -136
- package/pages/c/_cluster/fleet/application/index.vue +5 -3
- package/pages/c/_cluster/fleet/application/suse-app-collection/ChartDetailBody.vue +338 -0
- package/pages/c/_cluster/fleet/application/suse-app-collection/ChartDetailHeader.vue +121 -0
- package/pages/c/_cluster/fleet/application/suse-app-collection/chart.vue +369 -0
- package/pages/c/_cluster/fleet/application/suse-app-collection/charts.vue +248 -0
- package/pages/c/_cluster/fleet/application/suse-app-collection/credentials.vue +310 -0
- package/pages/c/_cluster/fleet/index.vue +2 -2
- package/pages/c/_cluster/uiplugins/__tests__/index.test.ts +96 -0
- package/pages/c/_cluster/uiplugins/index.vue +15 -0
- package/pages/fail-whale.vue +16 -11
- package/pages/home.vue +16 -46
- package/plugins/clean-html.d.ts +9 -0
- package/plugins/dashboard-store/__tests__/resource-class.test.ts +93 -0
- package/plugins/dashboard-store/resource-class.js +62 -7
- package/plugins/steve/__tests__/actions.test.ts +212 -0
- package/plugins/steve/actions.js +96 -0
- package/plugins/steve/steve-pagination-utils.ts +1 -1
- package/rancher-components/Accordion/Accordion.vue +53 -9
- package/rancher-components/Form/Checkbox/Checkbox.vue +14 -0
- package/rancher-components/Form/Radio/RadioButton.vue +17 -1
- package/rancher-components/Form/Radio/RadioGroup.vue +10 -0
- package/rancher-components/Pill/RcTag/RcTag.vue +3 -2
- package/rancher-components/RcButton/RcButton.test.ts +103 -0
- package/rancher-components/RcButton/RcButton.vue +94 -15
- package/rancher-components/RcButton/types.ts +3 -0
- package/rancher-components/RcItemCard/RcItemCard.test.ts +18 -0
- package/rancher-components/RcItemCard/RcItemCard.vue +2 -2
- package/rancher-components/RcSection/RcSection.vue +28 -3
- package/scripts/extension/helm/package/Dockerfile +1 -1
- package/scripts/test-plugins-build.sh +2 -1
- package/store/__tests__/notifications.test.ts +434 -0
- package/store/catalog.js +57 -0
- package/store/plugins.js +7 -4
- package/types/components/buttonGroup.ts +5 -0
- package/types/shell/index.d.ts +104 -70
- package/utils/__tests__/auth.test.ts +273 -0
- package/utils/__tests__/computed.test.ts +193 -0
- package/utils/__tests__/cspAdaptor.test.ts +163 -0
- package/utils/__tests__/dom.test.ts +81 -0
- package/utils/__tests__/duration.test.ts +37 -1
- package/utils/__tests__/dynamic-importer.test.ts +102 -0
- package/utils/__tests__/fleet-appco.test.ts +312 -0
- package/utils/__tests__/monitoring.test.ts +130 -0
- package/utils/__tests__/object.test.ts +22 -0
- package/utils/__tests__/platform.test.ts +91 -0
- package/utils/__tests__/position.test.ts +237 -0
- package/utils/__tests__/provider.test.ts +51 -1
- package/utils/__tests__/queue.test.ts +232 -0
- package/utils/__tests__/release-notes.test.ts +221 -0
- package/utils/__tests__/router.test.js +254 -1
- package/utils/__tests__/select.test.ts +208 -0
- package/utils/__tests__/time.test.ts +265 -1
- package/utils/__tests__/title.test.ts +47 -0
- package/utils/__tests__/width.test.ts +53 -0
- package/utils/__tests__/window.test.ts +158 -0
- package/utils/__tests__/xccdf.test.ts +126 -6
- package/utils/crypto/__tests__/browserHashUtils.test.ts +98 -0
- package/utils/crypto/__tests__/index.test.ts +144 -0
- package/utils/duration.ts +104 -0
- package/utils/dynamic-content/__tests__/notification-handler.test.ts +196 -0
- package/utils/dynamic-content/info.ts +2 -1
- package/utils/error.js +13 -0
- package/utils/fleet-appco.ts +323 -0
- package/utils/object.js +22 -2
- package/utils/provider.ts +12 -0
- package/utils/validators/__tests__/container-images.test.ts +104 -0
- package/utils/validators/__tests__/flow-output.test.ts +91 -0
- package/utils/validators/__tests__/logging-outputs.test.ts +58 -0
- package/utils/validators/__tests__/monitoring-route.test.ts +119 -0
- package/utils/xccdf.ts +39 -42
- package/vue.config.js +1 -1
- package/pages/support/index.vue +0 -264
- package/utils/duration.js +0 -43
package/edit/auth/azuread.vue
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
<script>
|
|
2
|
+
import { ref, computed } from 'vue';
|
|
3
|
+
import { useStore } from 'vuex';
|
|
2
4
|
import isEqual from 'lodash/isEqual';
|
|
3
5
|
import Loading from '@shell/components/Loading';
|
|
4
6
|
import CreateEditView from '@shell/mixins/create-edit-view';
|
|
5
|
-
import FormValidation from '@shell/mixins/form-validation';
|
|
6
7
|
import CruResource from '@shell/components/CruResource';
|
|
7
8
|
import InfoBox from '@shell/components/InfoBox';
|
|
8
9
|
import { RadioGroup } from '@components/Form/Radio';
|
|
@@ -16,6 +17,8 @@ import { AZURE_MIGRATED } from '@shell/config/labels-annotations';
|
|
|
16
17
|
import { get } from '@shell/utils/object';
|
|
17
18
|
import AuthProviderWarningBanners from '@shell/edit/auth/AuthProviderWarningBanners';
|
|
18
19
|
import formRulesGenerator from '@shell/utils/validators/formRules/index';
|
|
20
|
+
import { useFormValidation } from '@shell/composables/useFormValidation';
|
|
21
|
+
import { useI18n } from '@shell/composables/useI18n';
|
|
19
22
|
|
|
20
23
|
const TENANT_ID_TOKEN = '__[[TENANT_ID]]__';
|
|
21
24
|
|
|
@@ -68,7 +71,73 @@ export default {
|
|
|
68
71
|
AuthProviderWarningBanners
|
|
69
72
|
},
|
|
70
73
|
|
|
71
|
-
mixins: [CreateEditView, AuthConfig
|
|
74
|
+
mixins: [CreateEditView, AuthConfig],
|
|
75
|
+
|
|
76
|
+
setup() {
|
|
77
|
+
const store = useStore();
|
|
78
|
+
const { t } = useI18n(store);
|
|
79
|
+
|
|
80
|
+
const editMemberConfigRef = ref(false);
|
|
81
|
+
const isLogoutAllSupported = ref(false);
|
|
82
|
+
const sloTypeRef = ref(null);
|
|
83
|
+
const sloEndSessionEndpointUiEnabled = computed(() => (
|
|
84
|
+
sloTypeRef.value === SLO_OPTION_VALUES.all || sloTypeRef.value === SLO_OPTION_VALUES.both
|
|
85
|
+
));
|
|
86
|
+
|
|
87
|
+
const urlRule = formRulesGenerator(t, {}).genericUrl;
|
|
88
|
+
|
|
89
|
+
const extraRules = {
|
|
90
|
+
applicationSecretRequired: (value) => {
|
|
91
|
+
if (!editMemberConfigRef.value && !value) {
|
|
92
|
+
return t('validation.required', { key: t('authConfig.azuread.applicationSecret.label') });
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return undefined;
|
|
96
|
+
},
|
|
97
|
+
endSessionEndpointRequiredAndValid: (value) => {
|
|
98
|
+
if (!isLogoutAllSupported.value || !sloEndSessionEndpointUiEnabled.value) {
|
|
99
|
+
return undefined;
|
|
100
|
+
}
|
|
101
|
+
if (!value) {
|
|
102
|
+
return t('validation.required', { key: t('authConfig.azuread.endSessionEndpoint.title') });
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return urlRule(value);
|
|
106
|
+
},
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
const { getRules, isFormValid } = useFormValidation(t, [
|
|
110
|
+
{
|
|
111
|
+
path: 'tenantId', rules: ['required'], translationKey: 'authConfig.azuread.tenantId.label'
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
path: 'applicationId', rules: ['required'], translationKey: 'authConfig.azuread.applicationId.label'
|
|
115
|
+
},
|
|
116
|
+
{ path: 'applicationSecret', rules: ['applicationSecretRequired'] },
|
|
117
|
+
{
|
|
118
|
+
path: 'endpoint', rules: ['required', 'url'], translationKey: 'authConfig.azuread.endpoint.label'
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
path: 'graphEndpoint', rules: ['required', 'url'], translationKey: 'authConfig.azuread.graphEndpoint.label'
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
path: 'tokenEndpoint', rules: ['required', 'url'], translationKey: 'authConfig.azuread.tokenEndpoint.label'
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
path: 'authEndpoint', rules: ['required', 'url'], translationKey: 'authConfig.azuread.authEndpoint.label'
|
|
128
|
+
},
|
|
129
|
+
{ path: 'endSessionEndpoint', rules: ['endSessionEndpointRequiredAndValid'] },
|
|
130
|
+
], extraRules);
|
|
131
|
+
|
|
132
|
+
return {
|
|
133
|
+
getRules,
|
|
134
|
+
isFormValid,
|
|
135
|
+
editMemberConfigRef,
|
|
136
|
+
isLogoutAllSupported,
|
|
137
|
+
sloTypeRef,
|
|
138
|
+
sloEndSessionEndpointUiEnabled,
|
|
139
|
+
};
|
|
140
|
+
},
|
|
72
141
|
|
|
73
142
|
async fetch() {
|
|
74
143
|
await this.reloadModel();
|
|
@@ -89,39 +158,11 @@ export default {
|
|
|
89
158
|
|
|
90
159
|
// Storing the applicationSecret is necessary because norman doesn't support returning secrets and when we
|
|
91
160
|
// override the steve authconfig with a norman config the applicationSecret is lost
|
|
92
|
-
applicationSecret: this.value.applicationSecret
|
|
93
|
-
fvFormRuleSets: [
|
|
94
|
-
{ path: 'tenantId', rules: ['tenantIdRequired'] },
|
|
95
|
-
{ path: 'applicationId', rules: ['applicationIdRequired'] },
|
|
96
|
-
{ path: 'applicationSecret', rules: ['applicationSecretRequired'] },
|
|
97
|
-
{ path: 'endpoint', rules: ['endpointRequired', 'endpointMustBeURL'] },
|
|
98
|
-
{ path: 'graphEndpoint', rules: ['graphEndpointRequired', 'graphEndpointMustBeURL'] },
|
|
99
|
-
{ path: 'tokenEndpoint', rules: ['tokenEndpointRequired', 'tokenEndpointMustBeURL'] },
|
|
100
|
-
{ path: 'authEndpoint', rules: ['authEndpointRequired', 'authEndpointMustBeURL'] },
|
|
101
|
-
{ path: 'endSessionEndpoint', rules: ['endSessionEndpointRequiredAndValid'] },
|
|
102
|
-
]
|
|
161
|
+
applicationSecret: this.value.applicationSecret
|
|
103
162
|
};
|
|
104
163
|
},
|
|
105
164
|
|
|
106
165
|
computed: {
|
|
107
|
-
// Cannot pass this.model as a rootObject because it is undefined at that point, so had to use a workaround
|
|
108
|
-
fvExtraRules() {
|
|
109
|
-
return {
|
|
110
|
-
tenantIdRequired: this.modelFieldRequired('tenantId', 'authConfig.azuread.tenantId.label'),
|
|
111
|
-
applicationIdRequired: this.modelFieldRequired('applicationId', 'authConfig.azuread.applicationId.label'),
|
|
112
|
-
applicationSecretRequired: this.applicationSecretRequired(),
|
|
113
|
-
endpointRequired: this.modelFieldRequired('endpoint', 'authConfig.azuread.endpoint.label'),
|
|
114
|
-
endpointMustBeURL: this.modelFieldURL('endpoint'),
|
|
115
|
-
graphEndpointRequired: this.modelFieldRequired('graphEndpoint', 'authConfig.azuread.graphEndpoint.label'),
|
|
116
|
-
graphEndpointMustBeURL: this.modelFieldURL('graphEndpoint'),
|
|
117
|
-
tokenEndpointRequired: this.modelFieldRequired('tokenEndpoint', 'authConfig.azuread.tokenEndpoint.label'),
|
|
118
|
-
tokenEndpointMustBeURL: this.modelFieldURL('tokenEndpoint'),
|
|
119
|
-
authEndpointRequired: this.modelFieldRequired('authEndpoint', 'authConfig.azuread.authEndpoint.label'),
|
|
120
|
-
authEndpointMustBeURL: this.modelFieldURL('authEndpoint'),
|
|
121
|
-
endSessionEndpointRequiredAndValid: this.endSessionEndpointRule(),
|
|
122
|
-
};
|
|
123
|
-
},
|
|
124
|
-
|
|
125
166
|
tArgs() {
|
|
126
167
|
return {
|
|
127
168
|
baseUrl: this.baseUrl,
|
|
@@ -172,14 +213,14 @@ export default {
|
|
|
172
213
|
return this.model.enabled && !this.isEnabling && !this.editConfig;
|
|
173
214
|
},
|
|
174
215
|
|
|
175
|
-
|
|
176
|
-
return this.model
|
|
216
|
+
displayName() {
|
|
217
|
+
return this.t('model.authConfig.name.azuread');
|
|
177
218
|
},
|
|
178
219
|
|
|
179
220
|
sloOptions() {
|
|
180
221
|
return [
|
|
181
|
-
{ value: SLO_OPTION_VALUES.rancher, label: this.t('authConfig.slo.sloOptions.onlyRancher', { name: this.
|
|
182
|
-
{ value: SLO_OPTION_VALUES.all, label: this.t('authConfig.slo.sloOptions.logoutAll', { name: this.
|
|
222
|
+
{ value: SLO_OPTION_VALUES.rancher, label: this.t('authConfig.slo.sloOptions.onlyRancher', { name: this.displayName }) },
|
|
223
|
+
{ value: SLO_OPTION_VALUES.all, label: this.t('authConfig.slo.sloOptions.logoutAll', { name: this.displayName }) },
|
|
183
224
|
{ value: SLO_OPTION_VALUES.both, label: this.t('authConfig.slo.sloOptions.choose') },
|
|
184
225
|
];
|
|
185
226
|
},
|
|
@@ -190,12 +231,23 @@ export default {
|
|
|
190
231
|
return sloOptionSelected?.label || '';
|
|
191
232
|
},
|
|
192
233
|
|
|
193
|
-
sloEndSessionEndpointUiEnabled() {
|
|
194
|
-
return this.sloType === SLO_OPTION_VALUES.all || this.sloType === SLO_OPTION_VALUES.both;
|
|
195
|
-
},
|
|
196
234
|
},
|
|
197
235
|
|
|
198
236
|
watch: {
|
|
237
|
+
editMemberConfig: {
|
|
238
|
+
handler(val) {
|
|
239
|
+
this.editMemberConfigRef = val;
|
|
240
|
+
},
|
|
241
|
+
immediate: true,
|
|
242
|
+
},
|
|
243
|
+
|
|
244
|
+
'model.logoutAllSupported': {
|
|
245
|
+
handler(val) {
|
|
246
|
+
this.isLogoutAllSupported = !!val;
|
|
247
|
+
},
|
|
248
|
+
immediate: true,
|
|
249
|
+
},
|
|
250
|
+
|
|
199
251
|
endpoint(value) {
|
|
200
252
|
this.setEndpoints(value);
|
|
201
253
|
},
|
|
@@ -207,22 +259,26 @@ export default {
|
|
|
207
259
|
},
|
|
208
260
|
|
|
209
261
|
// sloType is defined on shell/mixins/auth-config.js
|
|
210
|
-
sloType
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
262
|
+
sloType: {
|
|
263
|
+
handler(neu) {
|
|
264
|
+
this.sloTypeRef = neu;
|
|
265
|
+
switch (neu) {
|
|
266
|
+
case SLO_OPTION_VALUES.rancher:
|
|
267
|
+
this.model.logoutAllEnabled = false;
|
|
268
|
+
this.model.logoutAllForced = false;
|
|
269
|
+
this.model.endSessionEndpoint = '';
|
|
270
|
+
break;
|
|
271
|
+
case SLO_OPTION_VALUES.all:
|
|
272
|
+
this.model.logoutAllEnabled = true;
|
|
273
|
+
this.model.logoutAllForced = true;
|
|
274
|
+
break;
|
|
275
|
+
case SLO_OPTION_VALUES.both:
|
|
276
|
+
this.model.logoutAllEnabled = true;
|
|
277
|
+
this.model.logoutAllForced = false;
|
|
278
|
+
break;
|
|
279
|
+
}
|
|
280
|
+
},
|
|
281
|
+
immediate: true,
|
|
226
282
|
},
|
|
227
283
|
|
|
228
284
|
model: {
|
|
@@ -324,37 +380,6 @@ export default {
|
|
|
324
380
|
});
|
|
325
381
|
}
|
|
326
382
|
},
|
|
327
|
-
modelFieldRequired(path, label) {
|
|
328
|
-
return () => {
|
|
329
|
-
return !this.model[path] ? `${ this.t('validation.required', { key: this.t(label) }) }` : undefined;
|
|
330
|
-
};
|
|
331
|
-
},
|
|
332
|
-
applicationSecretRequired() {
|
|
333
|
-
return () => {
|
|
334
|
-
return !this.editMemberConfig && !this.model.applicationSecret ? `${ this.t('validation.required', { key: this.t('authConfig.azuread.applicationSecret.label') }) }` : undefined;
|
|
335
|
-
};
|
|
336
|
-
},
|
|
337
|
-
modelFieldURL(path) {
|
|
338
|
-
return () => {
|
|
339
|
-
const rule = formRulesGenerator(this.$store.getters['i18n/t'], {}).url;
|
|
340
|
-
|
|
341
|
-
return rule(this.model[path]);
|
|
342
|
-
};
|
|
343
|
-
},
|
|
344
|
-
|
|
345
|
-
endSessionEndpointRule() {
|
|
346
|
-
return () => {
|
|
347
|
-
if (!this.isLogoutAllSupported || !this.sloEndSessionEndpointUiEnabled) {
|
|
348
|
-
return undefined;
|
|
349
|
-
}
|
|
350
|
-
if (!this.model.endSessionEndpoint) {
|
|
351
|
-
return this.t('validation.required', { key: this.t('authConfig.azuread.endSessionEndpoint.title') });
|
|
352
|
-
}
|
|
353
|
-
const rule = formRulesGenerator(this.$store.getters['i18n/t'], {}).url;
|
|
354
|
-
|
|
355
|
-
return rule(this.model.endSessionEndpoint);
|
|
356
|
-
};
|
|
357
|
-
},
|
|
358
383
|
}
|
|
359
384
|
};
|
|
360
385
|
</script>
|
|
@@ -367,7 +392,7 @@ export default {
|
|
|
367
392
|
:mode="mode"
|
|
368
393
|
:resource="model"
|
|
369
394
|
:subtypes="[]"
|
|
370
|
-
:validation-passed="
|
|
395
|
+
:validation-passed="isFormValid"
|
|
371
396
|
:finish-button-mode="model && model.enabled ? 'edit' : 'enable'"
|
|
372
397
|
:can-yaml="false"
|
|
373
398
|
:errors="errors"
|
|
@@ -466,10 +491,11 @@ export default {
|
|
|
466
491
|
<LabeledInput
|
|
467
492
|
id="tenant-id"
|
|
468
493
|
v-model:value="model.tenantId"
|
|
494
|
+
name="tenantId"
|
|
469
495
|
:label="t('authConfig.azuread.tenantId.label')"
|
|
470
496
|
:mode="mode"
|
|
471
497
|
:required="true"
|
|
472
|
-
:rules="
|
|
498
|
+
:rules="getRules('tenantId')"
|
|
473
499
|
:tooltip="t('authConfig.azuread.tenantId.tooltip')"
|
|
474
500
|
:placeholder="t('authConfig.azuread.tenantId.placeholder')"
|
|
475
501
|
data-testid="input-azureAD-tenantId"
|
|
@@ -481,10 +507,11 @@ export default {
|
|
|
481
507
|
<LabeledInput
|
|
482
508
|
id="application-id"
|
|
483
509
|
v-model:value="model.applicationId"
|
|
510
|
+
name="applicationId"
|
|
484
511
|
:label="t('authConfig.azuread.applicationId.label')"
|
|
485
512
|
:mode="mode"
|
|
486
513
|
:required="true"
|
|
487
|
-
:rules="
|
|
514
|
+
:rules="getRules('applicationId')"
|
|
488
515
|
:placeholder="t('authConfig.azuread.applicationId.placeholder')"
|
|
489
516
|
data-testid="input-azureAD-applcationId"
|
|
490
517
|
/>
|
|
@@ -493,10 +520,11 @@ export default {
|
|
|
493
520
|
<LabeledInput
|
|
494
521
|
id="application-secret"
|
|
495
522
|
v-model:value="model.applicationSecret"
|
|
523
|
+
name="applicationSecret"
|
|
496
524
|
type="password"
|
|
497
525
|
:label="t('authConfig.azuread.applicationSecret.label')"
|
|
498
526
|
:required="true"
|
|
499
|
-
:rules="
|
|
527
|
+
:rules="getRules('applicationSecret')"
|
|
500
528
|
:mode="mode"
|
|
501
529
|
data-testid="input-azureAD-applicationSecret"
|
|
502
530
|
/>
|
|
@@ -548,19 +576,21 @@ export default {
|
|
|
548
576
|
<div class="col span-6">
|
|
549
577
|
<LabeledInput
|
|
550
578
|
v-model:value="model.endpoint"
|
|
579
|
+
name="endpoint"
|
|
551
580
|
:label="t('authConfig.azuread.endpoint.label')"
|
|
552
581
|
:mode="mode"
|
|
553
582
|
:required="true"
|
|
554
|
-
:rules="
|
|
583
|
+
:rules="getRules('endpoint')"
|
|
555
584
|
data-testid="input-azureAD-endpoint"
|
|
556
585
|
/>
|
|
557
586
|
</div>
|
|
558
587
|
<div class="col span-6">
|
|
559
588
|
<LabeledInput
|
|
560
589
|
v-model:value="model.graphEndpoint"
|
|
590
|
+
name="graphEndpoint"
|
|
561
591
|
:label="t('authConfig.azuread.graphEndpoint.label')"
|
|
562
592
|
:required="true"
|
|
563
|
-
:rules="
|
|
593
|
+
:rules="getRules('graphEndpoint')"
|
|
564
594
|
:mode="mode"
|
|
565
595
|
data-testid="input-azureAD-graphEndpoint"
|
|
566
596
|
/>
|
|
@@ -570,19 +600,21 @@ export default {
|
|
|
570
600
|
<div class="col span-6">
|
|
571
601
|
<LabeledInput
|
|
572
602
|
v-model:value="model.tokenEndpoint"
|
|
603
|
+
name="tokenEndpoint"
|
|
573
604
|
:label="t('authConfig.azuread.tokenEndpoint.label')"
|
|
574
605
|
:mode="mode"
|
|
575
606
|
:required="true"
|
|
576
|
-
:rules="
|
|
607
|
+
:rules="getRules('tokenEndpoint')"
|
|
577
608
|
data-testid="input-azureAD-tokenEndpoint"
|
|
578
609
|
/>
|
|
579
610
|
</div>
|
|
580
611
|
<div class="col span-6">
|
|
581
612
|
<LabeledInput
|
|
582
613
|
v-model:value="model.authEndpoint"
|
|
614
|
+
name="authEndpoint"
|
|
583
615
|
:label="t('authConfig.azuread.authEndpoint.label')"
|
|
584
616
|
:required="true"
|
|
585
|
-
:rules="
|
|
617
|
+
:rules="getRules('authEndpoint')"
|
|
586
618
|
:mode="mode"
|
|
587
619
|
data-testid="input-azureAD-authEndpoint"
|
|
588
620
|
/>
|
|
@@ -619,10 +651,11 @@ export default {
|
|
|
619
651
|
<div class="col span-6">
|
|
620
652
|
<LabeledInput
|
|
621
653
|
v-model:value="model.endSessionEndpoint"
|
|
622
|
-
|
|
654
|
+
name="endSessionEndpoint"
|
|
655
|
+
:tooltip="t('authConfig.azuread.endSessionEndpoint.tooltip', { name: displayName, tenantId: `${ tenantId || 'tenant-id' }` }, true)"
|
|
623
656
|
:label="t('authConfig.azuread.endSessionEndpoint.title')"
|
|
624
657
|
:mode="mode"
|
|
625
|
-
:rules="
|
|
658
|
+
:rules="getRules('endSessionEndpoint')"
|
|
626
659
|
:required="true"
|
|
627
660
|
data-testid="azuread-endSessionEndpoint"
|
|
628
661
|
/>
|
package/edit/auth/github.vue
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
<script>
|
|
2
|
+
import { ref, computed, provide } from 'vue';
|
|
3
|
+
import { useStore } from 'vuex';
|
|
4
|
+
import { useForm } from 'vee-validate';
|
|
5
|
+
import { toTypedSchema } from '@vee-validate/zod';
|
|
6
|
+
import * as z from 'zod';
|
|
2
7
|
import Loading from '@shell/components/Loading';
|
|
3
8
|
import CreateEditView from '@shell/mixins/create-edit-view';
|
|
4
9
|
import CruResource from '@shell/components/CruResource';
|
|
@@ -13,6 +18,7 @@ import AuthProviderWarningBanners from '@shell/edit/auth/AuthProviderWarningBann
|
|
|
13
18
|
import FileSelector from '@shell/components/form/FileSelector';
|
|
14
19
|
import GithubSteps from '@shell/edit/auth/github-steps.vue';
|
|
15
20
|
import GithubAppSteps from '@shell/edit/auth/github-app-steps.vue';
|
|
21
|
+
import { useI18n } from '@shell/composables/useI18n';
|
|
16
22
|
|
|
17
23
|
export default {
|
|
18
24
|
components: {
|
|
@@ -30,6 +36,49 @@ export default {
|
|
|
30
36
|
|
|
31
37
|
mixins: [CreateEditView, AuthConfig],
|
|
32
38
|
|
|
39
|
+
setup() {
|
|
40
|
+
const store = useStore();
|
|
41
|
+
const { t } = useI18n(store);
|
|
42
|
+
|
|
43
|
+
// These refs sync Options API state into the Composition API for the reactive schema.
|
|
44
|
+
const isGithubAppRef = ref(false);
|
|
45
|
+
const isPublicRef = ref(true);
|
|
46
|
+
|
|
47
|
+
const coerce = (schema) => z.preprocess((v) => v ?? '', schema);
|
|
48
|
+
const requiredField = (key) => coerce(z.string().min(1, t('validation.required', { key: t(key) })));
|
|
49
|
+
const requiredUrlField = (key) => coerce(z.string().min(1, t('validation.required', { key: t(key) })).url(t('validation.genericUrl')));
|
|
50
|
+
const optionalField = coerce(z.string());
|
|
51
|
+
|
|
52
|
+
const validationSchema = computed(() => toTypedSchema(
|
|
53
|
+
z.object({
|
|
54
|
+
clientId: requiredField('authConfig.github.clientId.label'),
|
|
55
|
+
clientSecret: requiredField('authConfig.github.clientSecret.label'),
|
|
56
|
+
appId: isGithubAppRef.value ? requiredField('authConfig.githubapp.githubAppId.label') : optionalField,
|
|
57
|
+
privateKey: isGithubAppRef.value ? requiredField('authConfig.githubapp.privateKey.label') : optionalField,
|
|
58
|
+
targetUrl: !isPublicRef.value ? requiredUrlField('authConfig.github.host.label') : optionalField,
|
|
59
|
+
})
|
|
60
|
+
));
|
|
61
|
+
|
|
62
|
+
const showAllErrors = ref(false);
|
|
63
|
+
|
|
64
|
+
provide('vee-show-all-errors', showAllErrors);
|
|
65
|
+
|
|
66
|
+
const { errors, validate } = useForm({ validationSchema });
|
|
67
|
+
const isFormValid = computed(() => Object.keys(errors.value).length === 0);
|
|
68
|
+
|
|
69
|
+
const validateAllFields = async() => {
|
|
70
|
+
await validate();
|
|
71
|
+
showAllErrors.value = true;
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
return {
|
|
75
|
+
isGithubAppRef,
|
|
76
|
+
isPublicRef,
|
|
77
|
+
isFormValid,
|
|
78
|
+
validateAllFields,
|
|
79
|
+
};
|
|
80
|
+
},
|
|
81
|
+
|
|
33
82
|
async fetch() {
|
|
34
83
|
await this.mixinFetch();
|
|
35
84
|
|
|
@@ -97,32 +146,37 @@ export default {
|
|
|
97
146
|
},
|
|
98
147
|
|
|
99
148
|
validationPassed() {
|
|
100
|
-
// Allows for configuring authorized users and groups
|
|
101
149
|
if ( this.model.enabled && !this.editConfig ) {
|
|
102
150
|
return true;
|
|
103
151
|
}
|
|
104
152
|
|
|
105
|
-
|
|
106
|
-
return false;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
if (this.isGithubApp && (!this.model.appId || !this.model.privateKey)) {
|
|
110
|
-
return false;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
return true;
|
|
153
|
+
return this.isFormValid;
|
|
114
154
|
},
|
|
115
155
|
|
|
116
156
|
},
|
|
117
157
|
|
|
118
158
|
watch: {
|
|
119
|
-
|
|
120
|
-
|
|
159
|
+
'model.id': {
|
|
160
|
+
handler(newVal) {
|
|
161
|
+
this.isGithubAppRef = newVal === 'githubapp';
|
|
162
|
+
},
|
|
163
|
+
immediate: true,
|
|
164
|
+
},
|
|
165
|
+
|
|
166
|
+
targetType: {
|
|
167
|
+
handler(newVal) {
|
|
168
|
+
this.isPublicRef = newVal === 'public';
|
|
169
|
+
this.updateHost();
|
|
170
|
+
},
|
|
171
|
+
immediate: true,
|
|
172
|
+
},
|
|
173
|
+
|
|
174
|
+
targetUrl: 'updateHost',
|
|
121
175
|
},
|
|
122
176
|
|
|
123
177
|
methods: {
|
|
124
178
|
updateHost() {
|
|
125
|
-
const match = this.targetUrl
|
|
179
|
+
const match = this.targetUrl?.match(/^(((https?):)?\/\/)?([^/]+)(\/.*)?$/);
|
|
126
180
|
|
|
127
181
|
if ( match ) {
|
|
128
182
|
if ( match[3] === 'http') {
|
|
@@ -212,6 +266,7 @@ export default {
|
|
|
212
266
|
<LabeledInput
|
|
213
267
|
v-if="!isPublic"
|
|
214
268
|
v-model:value="targetUrl"
|
|
269
|
+
name="targetUrl"
|
|
215
270
|
:label-key="`authConfig.${NAME}.host.label`"
|
|
216
271
|
:placeholder="t(`authConfig.${NAME}.host.placeholder`)"
|
|
217
272
|
:required="true"
|
|
@@ -231,6 +286,7 @@ export default {
|
|
|
231
286
|
<div class="col span-6">
|
|
232
287
|
<LabeledInput
|
|
233
288
|
v-model:value="model.clientId"
|
|
289
|
+
name="clientId"
|
|
234
290
|
required
|
|
235
291
|
data-testid="client-id"
|
|
236
292
|
:label="t(`authConfig.${NAME}.clientId.label`)"
|
|
@@ -240,6 +296,7 @@ export default {
|
|
|
240
296
|
<div class="col span-6">
|
|
241
297
|
<LabeledInput
|
|
242
298
|
v-model:value="model.clientSecret"
|
|
299
|
+
name="clientSecret"
|
|
243
300
|
required
|
|
244
301
|
data-testid="client-secret"
|
|
245
302
|
type="password"
|
|
@@ -253,6 +310,7 @@ export default {
|
|
|
253
310
|
<div class="col span-6">
|
|
254
311
|
<LabeledInput
|
|
255
312
|
v-model:value="model.appId"
|
|
313
|
+
name="appId"
|
|
256
314
|
required
|
|
257
315
|
data-testid="app-id"
|
|
258
316
|
:label="t(`authConfig.${NAME}.githubAppId.label`)"
|
|
@@ -272,6 +330,7 @@ export default {
|
|
|
272
330
|
<div class="col span-6">
|
|
273
331
|
<LabeledInput
|
|
274
332
|
v-model:value="model.privateKey"
|
|
333
|
+
name="privateKey"
|
|
275
334
|
required
|
|
276
335
|
data-testid="private-key"
|
|
277
336
|
type="multiline"
|