More permissions
This commit is contained in:
@@ -18,16 +18,17 @@
|
||||
Lets users discover the workspace if they sign up with a matching email.
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
v-tippy="
|
||||
!isWorkspaceAdmin
|
||||
? 'You must be a workspace admin'
|
||||
: !hasWorkspaceDomains
|
||||
? 'Your workspace must have at least one verified domain'
|
||||
: undefined
|
||||
"
|
||||
>
|
||||
<FormSwitch
|
||||
v-model="isDomainDiscoverabilityEnabled"
|
||||
v-tippy="
|
||||
!isWorkspaceAdmin
|
||||
? 'You must be a workspace admin'
|
||||
: !hasWorkspaceDomains
|
||||
? 'Your workspace must have at least one verified domain'
|
||||
: undefined
|
||||
"
|
||||
name="domain-discoverability"
|
||||
:disabled="!hasWorkspaceDomains || !isWorkspaceAdmin"
|
||||
:show-label="false"
|
||||
@@ -112,10 +113,6 @@ graphql(`
|
||||
discoverabilityEnabled
|
||||
discoverabilityAutoJoinEnabled
|
||||
domainBasedMembershipProtectionEnabled
|
||||
hasAccessToDomainBasedSecurityPolicies: hasAccessToFeature(
|
||||
featureName: domainBasedSecurityPolicies
|
||||
)
|
||||
hasAccessToSSO: hasAccessToFeature(featureName: oidcSso)
|
||||
}
|
||||
`)
|
||||
|
||||
@@ -154,6 +151,13 @@ const isDomainDiscoverabilityEnabled = computed({
|
||||
}).catch(convertThrowIntoFetchResult)
|
||||
|
||||
if (result?.data) {
|
||||
triggerNotification({
|
||||
type: ToastNotificationType.Success,
|
||||
title: 'Workspace discoverability updated',
|
||||
description: `Workspace discoverability has been ${
|
||||
newVal ? 'enabled' : 'disabled'
|
||||
}`
|
||||
})
|
||||
mixpanel.track('Workspace Discoverability Toggled', {
|
||||
value: newVal,
|
||||
// eslint-disable-next-line camelcase
|
||||
|
||||
@@ -13,7 +13,11 @@
|
||||
Only allow users with verified domains to join the workspace
|
||||
</p>
|
||||
</div>
|
||||
<div key="tooltipText" v-tippy="switchDisabled ? tooltipText : undefined">
|
||||
<div
|
||||
v-if="props.workspace?.hasAccessToDomainBasedSecurityPolicies"
|
||||
key="tooltipText"
|
||||
v-tippy="switchDisabled ? tooltipText : undefined"
|
||||
>
|
||||
<!-- Never disable switch when domain protection is enabled to
|
||||
allow expired workspaces ability to downgrade-->
|
||||
<FormSwitch
|
||||
@@ -23,6 +27,23 @@
|
||||
name="domain-protection"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
v-else
|
||||
v-tippy="
|
||||
props.workspace?.role !== Roles.Workspace.Admin
|
||||
? 'You must be a workspace admin'
|
||||
: undefined
|
||||
"
|
||||
>
|
||||
<FormButton
|
||||
:to="settingsWorkspaceRoutes.billing.route(workspace.slug)"
|
||||
size="sm"
|
||||
color="outline"
|
||||
:disabled="props.workspace?.role !== Roles.Workspace.Admin"
|
||||
>
|
||||
Upgrade to Business
|
||||
</FormButton>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
@@ -34,10 +55,12 @@ import { graphql } from '~/lib/common/generated/gql'
|
||||
import type { SettingsWorkspacesSecurityDomainProtection_WorkspaceFragment } from '~/lib/common/generated/gql/graphql'
|
||||
import { useMixpanel } from '~/lib/core/composables/mp'
|
||||
import { workspaceUpdateDomainProtectionMutation } from '~/lib/workspaces/graphql/mutations'
|
||||
import { settingsWorkspaceRoutes } from '~/lib/common/helpers/route'
|
||||
|
||||
graphql(`
|
||||
fragment SettingsWorkspacesSecurityDomainProtection_Workspace on Workspace {
|
||||
id
|
||||
slug
|
||||
role
|
||||
domainBasedMembershipProtectionEnabled
|
||||
hasAccessToDomainBasedSecurityPolicies: hasAccessToFeature(
|
||||
@@ -57,6 +80,7 @@ const mixpanel = useMixpanel()
|
||||
const { mutate: updateDomainProtection } = useMutation(
|
||||
workspaceUpdateDomainProtectionMutation
|
||||
)
|
||||
const { triggerNotification } = useGlobalToast()
|
||||
|
||||
const hasWorkspaceDomains = computed(() => (props.workspace?.domains?.length || 0) > 0)
|
||||
|
||||
@@ -73,6 +97,11 @@ const isDomainProtectionEnabled = computed({
|
||||
}).catch(convertThrowIntoFetchResult)
|
||||
|
||||
if (result?.data) {
|
||||
triggerNotification({
|
||||
type: ToastNotificationType.Success,
|
||||
title: 'Domain protection updated',
|
||||
description: `Domain protection has been ${newVal ? 'enabled' : 'disabled'}`
|
||||
})
|
||||
mixpanel.track('Workspace Domain Protection Toggled', {
|
||||
value: newVal,
|
||||
// eslint-disable-next-line camelcase
|
||||
@@ -85,7 +114,6 @@ const isDomainProtectionEnabled = computed({
|
||||
const switchDisabled = computed(() => {
|
||||
if (props.workspace?.role !== Roles.Workspace.Admin) return true
|
||||
if (isDomainProtectionEnabled.value) return false
|
||||
if (!props.workspace?.hasAccessToDomainBasedSecurityPolicies) return true
|
||||
if (!hasWorkspaceDomains.value) return true
|
||||
return false
|
||||
})
|
||||
@@ -94,8 +122,6 @@ const tooltipText = computed(() => {
|
||||
if (props.workspace?.role !== Roles.Workspace.Admin)
|
||||
return 'You must be a workspace admin'
|
||||
if (isDomainProtectionEnabled.value) return undefined
|
||||
if (!props.workspace?.hasAccessToDomainBasedSecurityPolicies)
|
||||
return 'Business plan required'
|
||||
if (!hasWorkspaceDomains.value)
|
||||
return 'Your workspace must have at least one verified domain'
|
||||
return undefined
|
||||
|
||||
@@ -18,11 +18,20 @@
|
||||
</div>
|
||||
<div>
|
||||
<!-- Case 1: User doesn't have SSO access/plan -->
|
||||
<div v-if="!workspace.hasAccessToSSO">
|
||||
<p class="text-body-xs text-foreground-2 mb-2">
|
||||
SSO requires a Business subscription
|
||||
</p>
|
||||
<FormButton :to="settingsWorkspaceRoutes.billing.route(workspace.slug)">
|
||||
<div
|
||||
v-if="!workspace.hasAccessToSSO"
|
||||
v-tippy="
|
||||
props.workspace?.role !== Roles.Workspace.Admin
|
||||
? 'You must be a workspace admin'
|
||||
: undefined
|
||||
"
|
||||
>
|
||||
<FormButton
|
||||
:to="settingsWorkspaceRoutes.billing.route(workspace.slug)"
|
||||
size="sm"
|
||||
color="outline"
|
||||
:disabled="props.workspace?.role !== Roles.Workspace.Admin"
|
||||
>
|
||||
Upgrade to Business
|
||||
</FormButton>
|
||||
</div>
|
||||
@@ -63,13 +72,6 @@
|
||||
</div>
|
||||
|
||||
<template v-else>
|
||||
<CommonCard
|
||||
v-if="!workspace.hasAccessToSSO && workspace.sso?.provider?.id"
|
||||
class="bg-foundation"
|
||||
>
|
||||
SSO access requires an active Business subscription.
|
||||
</CommonCard>
|
||||
|
||||
<!-- Existing Provider Configuration -->
|
||||
<div v-if="provider" class="p-4 border border-outline-3 rounded-lg">
|
||||
<div v-if="!isEditing" class="flex items-center justify-between">
|
||||
|
||||
@@ -133,9 +133,9 @@ type Documents = {
|
||||
"\n query WorkspaceAvailableEditorSeats($slug: String!) {\n workspaceBySlug(slug: $slug) {\n id\n seats {\n editors {\n available\n }\n }\n }\n }\n": typeof types.WorkspaceAvailableEditorSeatsDocument,
|
||||
"\n fragment SettingsWorkspacesRegionsSelect_ServerRegionItem on ServerRegionItem {\n id\n key\n name\n description\n }\n": typeof types.SettingsWorkspacesRegionsSelect_ServerRegionItemFragmentDoc,
|
||||
"\n fragment SettingsWorkspacesSecurityDefaultSeat_Workspace on Workspace {\n id\n slug\n defaultSeatType\n discoverabilityAutoJoinEnabled\n role\n }\n": typeof types.SettingsWorkspacesSecurityDefaultSeat_WorkspaceFragmentDoc,
|
||||
"\n fragment SettingsWorkspacesSecurityDiscoverability_Workspace on Workspace {\n id\n slug\n role\n domains {\n id\n domain\n }\n sso {\n provider {\n id\n }\n }\n discoverabilityEnabled\n discoverabilityAutoJoinEnabled\n domainBasedMembershipProtectionEnabled\n hasAccessToDomainBasedSecurityPolicies: hasAccessToFeature(\n featureName: domainBasedSecurityPolicies\n )\n hasAccessToSSO: hasAccessToFeature(featureName: oidcSso)\n }\n": typeof types.SettingsWorkspacesSecurityDiscoverability_WorkspaceFragmentDoc,
|
||||
"\n fragment SettingsWorkspacesSecurityDiscoverability_Workspace on Workspace {\n id\n slug\n role\n domains {\n id\n domain\n }\n sso {\n provider {\n id\n }\n }\n discoverabilityEnabled\n discoverabilityAutoJoinEnabled\n domainBasedMembershipProtectionEnabled\n }\n": typeof types.SettingsWorkspacesSecurityDiscoverability_WorkspaceFragmentDoc,
|
||||
"\n fragment SettingsWorkspacesSecurityDomainManagement_Workspace on Workspace {\n id\n role\n discoverabilityEnabled\n domainBasedMembershipProtectionEnabled\n hasAccessToDomainBasedSecurityPolicies: hasAccessToFeature(\n featureName: domainBasedSecurityPolicies\n )\n hasAccessToSSO: hasAccessToFeature(featureName: oidcSso)\n domains {\n id\n domain\n }\n }\n": typeof types.SettingsWorkspacesSecurityDomainManagement_WorkspaceFragmentDoc,
|
||||
"\n fragment SettingsWorkspacesSecurityDomainProtection_Workspace on Workspace {\n id\n role\n domainBasedMembershipProtectionEnabled\n hasAccessToDomainBasedSecurityPolicies: hasAccessToFeature(\n featureName: domainBasedSecurityPolicies\n )\n domains {\n id\n }\n }\n": typeof types.SettingsWorkspacesSecurityDomainProtection_WorkspaceFragmentDoc,
|
||||
"\n fragment SettingsWorkspacesSecurityDomainProtection_Workspace on Workspace {\n id\n slug\n role\n domainBasedMembershipProtectionEnabled\n hasAccessToDomainBasedSecurityPolicies: hasAccessToFeature(\n featureName: domainBasedSecurityPolicies\n )\n domains {\n id\n }\n }\n": typeof types.SettingsWorkspacesSecurityDomainProtection_WorkspaceFragmentDoc,
|
||||
"\n fragment SettingsWorkspacesSecurityDomainRemoveDialog_WorkspaceDomain on WorkspaceDomain {\n id\n domain\n }\n": typeof types.SettingsWorkspacesSecurityDomainRemoveDialog_WorkspaceDomainFragmentDoc,
|
||||
"\n fragment SettingsWorkspacesSecurityDomainRemoveDialog_Workspace on Workspace {\n id\n domains {\n ...SettingsWorkspacesSecurityDomainRemoveDialog_WorkspaceDomain\n }\n }\n": typeof types.SettingsWorkspacesSecurityDomainRemoveDialog_WorkspaceFragmentDoc,
|
||||
"\n fragment SettingsWorkspacesSecuritySsoWrapper_Workspace on Workspace {\n id\n role\n slug\n sso {\n provider {\n id\n name\n clientId\n issuerUrl\n }\n }\n hasAccessToSSO: hasAccessToFeature(featureName: oidcSso)\n }\n": typeof types.SettingsWorkspacesSecuritySsoWrapper_WorkspaceFragmentDoc,
|
||||
@@ -578,9 +578,9 @@ const documents: Documents = {
|
||||
"\n query WorkspaceAvailableEditorSeats($slug: String!) {\n workspaceBySlug(slug: $slug) {\n id\n seats {\n editors {\n available\n }\n }\n }\n }\n": types.WorkspaceAvailableEditorSeatsDocument,
|
||||
"\n fragment SettingsWorkspacesRegionsSelect_ServerRegionItem on ServerRegionItem {\n id\n key\n name\n description\n }\n": types.SettingsWorkspacesRegionsSelect_ServerRegionItemFragmentDoc,
|
||||
"\n fragment SettingsWorkspacesSecurityDefaultSeat_Workspace on Workspace {\n id\n slug\n defaultSeatType\n discoverabilityAutoJoinEnabled\n role\n }\n": types.SettingsWorkspacesSecurityDefaultSeat_WorkspaceFragmentDoc,
|
||||
"\n fragment SettingsWorkspacesSecurityDiscoverability_Workspace on Workspace {\n id\n slug\n role\n domains {\n id\n domain\n }\n sso {\n provider {\n id\n }\n }\n discoverabilityEnabled\n discoverabilityAutoJoinEnabled\n domainBasedMembershipProtectionEnabled\n hasAccessToDomainBasedSecurityPolicies: hasAccessToFeature(\n featureName: domainBasedSecurityPolicies\n )\n hasAccessToSSO: hasAccessToFeature(featureName: oidcSso)\n }\n": types.SettingsWorkspacesSecurityDiscoverability_WorkspaceFragmentDoc,
|
||||
"\n fragment SettingsWorkspacesSecurityDiscoverability_Workspace on Workspace {\n id\n slug\n role\n domains {\n id\n domain\n }\n sso {\n provider {\n id\n }\n }\n discoverabilityEnabled\n discoverabilityAutoJoinEnabled\n domainBasedMembershipProtectionEnabled\n }\n": types.SettingsWorkspacesSecurityDiscoverability_WorkspaceFragmentDoc,
|
||||
"\n fragment SettingsWorkspacesSecurityDomainManagement_Workspace on Workspace {\n id\n role\n discoverabilityEnabled\n domainBasedMembershipProtectionEnabled\n hasAccessToDomainBasedSecurityPolicies: hasAccessToFeature(\n featureName: domainBasedSecurityPolicies\n )\n hasAccessToSSO: hasAccessToFeature(featureName: oidcSso)\n domains {\n id\n domain\n }\n }\n": types.SettingsWorkspacesSecurityDomainManagement_WorkspaceFragmentDoc,
|
||||
"\n fragment SettingsWorkspacesSecurityDomainProtection_Workspace on Workspace {\n id\n role\n domainBasedMembershipProtectionEnabled\n hasAccessToDomainBasedSecurityPolicies: hasAccessToFeature(\n featureName: domainBasedSecurityPolicies\n )\n domains {\n id\n }\n }\n": types.SettingsWorkspacesSecurityDomainProtection_WorkspaceFragmentDoc,
|
||||
"\n fragment SettingsWorkspacesSecurityDomainProtection_Workspace on Workspace {\n id\n slug\n role\n domainBasedMembershipProtectionEnabled\n hasAccessToDomainBasedSecurityPolicies: hasAccessToFeature(\n featureName: domainBasedSecurityPolicies\n )\n domains {\n id\n }\n }\n": types.SettingsWorkspacesSecurityDomainProtection_WorkspaceFragmentDoc,
|
||||
"\n fragment SettingsWorkspacesSecurityDomainRemoveDialog_WorkspaceDomain on WorkspaceDomain {\n id\n domain\n }\n": types.SettingsWorkspacesSecurityDomainRemoveDialog_WorkspaceDomainFragmentDoc,
|
||||
"\n fragment SettingsWorkspacesSecurityDomainRemoveDialog_Workspace on Workspace {\n id\n domains {\n ...SettingsWorkspacesSecurityDomainRemoveDialog_WorkspaceDomain\n }\n }\n": types.SettingsWorkspacesSecurityDomainRemoveDialog_WorkspaceFragmentDoc,
|
||||
"\n fragment SettingsWorkspacesSecuritySsoWrapper_Workspace on Workspace {\n id\n role\n slug\n sso {\n provider {\n id\n name\n clientId\n issuerUrl\n }\n }\n hasAccessToSSO: hasAccessToFeature(featureName: oidcSso)\n }\n": types.SettingsWorkspacesSecuritySsoWrapper_WorkspaceFragmentDoc,
|
||||
@@ -1397,7 +1397,7 @@ export function graphql(source: "\n fragment SettingsWorkspacesSecurityDefaultS
|
||||
/**
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
export function graphql(source: "\n fragment SettingsWorkspacesSecurityDiscoverability_Workspace on Workspace {\n id\n slug\n role\n domains {\n id\n domain\n }\n sso {\n provider {\n id\n }\n }\n discoverabilityEnabled\n discoverabilityAutoJoinEnabled\n domainBasedMembershipProtectionEnabled\n hasAccessToDomainBasedSecurityPolicies: hasAccessToFeature(\n featureName: domainBasedSecurityPolicies\n )\n hasAccessToSSO: hasAccessToFeature(featureName: oidcSso)\n }\n"): (typeof documents)["\n fragment SettingsWorkspacesSecurityDiscoverability_Workspace on Workspace {\n id\n slug\n role\n domains {\n id\n domain\n }\n sso {\n provider {\n id\n }\n }\n discoverabilityEnabled\n discoverabilityAutoJoinEnabled\n domainBasedMembershipProtectionEnabled\n hasAccessToDomainBasedSecurityPolicies: hasAccessToFeature(\n featureName: domainBasedSecurityPolicies\n )\n hasAccessToSSO: hasAccessToFeature(featureName: oidcSso)\n }\n"];
|
||||
export function graphql(source: "\n fragment SettingsWorkspacesSecurityDiscoverability_Workspace on Workspace {\n id\n slug\n role\n domains {\n id\n domain\n }\n sso {\n provider {\n id\n }\n }\n discoverabilityEnabled\n discoverabilityAutoJoinEnabled\n domainBasedMembershipProtectionEnabled\n }\n"): (typeof documents)["\n fragment SettingsWorkspacesSecurityDiscoverability_Workspace on Workspace {\n id\n slug\n role\n domains {\n id\n domain\n }\n sso {\n provider {\n id\n }\n }\n discoverabilityEnabled\n discoverabilityAutoJoinEnabled\n domainBasedMembershipProtectionEnabled\n }\n"];
|
||||
/**
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
@@ -1405,7 +1405,7 @@ export function graphql(source: "\n fragment SettingsWorkspacesSecurityDomainMa
|
||||
/**
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
export function graphql(source: "\n fragment SettingsWorkspacesSecurityDomainProtection_Workspace on Workspace {\n id\n role\n domainBasedMembershipProtectionEnabled\n hasAccessToDomainBasedSecurityPolicies: hasAccessToFeature(\n featureName: domainBasedSecurityPolicies\n )\n domains {\n id\n }\n }\n"): (typeof documents)["\n fragment SettingsWorkspacesSecurityDomainProtection_Workspace on Workspace {\n id\n role\n domainBasedMembershipProtectionEnabled\n hasAccessToDomainBasedSecurityPolicies: hasAccessToFeature(\n featureName: domainBasedSecurityPolicies\n )\n domains {\n id\n }\n }\n"];
|
||||
export function graphql(source: "\n fragment SettingsWorkspacesSecurityDomainProtection_Workspace on Workspace {\n id\n slug\n role\n domainBasedMembershipProtectionEnabled\n hasAccessToDomainBasedSecurityPolicies: hasAccessToFeature(\n featureName: domainBasedSecurityPolicies\n )\n domains {\n id\n }\n }\n"): (typeof documents)["\n fragment SettingsWorkspacesSecurityDomainProtection_Workspace on Workspace {\n id\n slug\n role\n domainBasedMembershipProtectionEnabled\n hasAccessToDomainBasedSecurityPolicies: hasAccessToFeature(\n featureName: domainBasedSecurityPolicies\n )\n domains {\n id\n }\n }\n"];
|
||||
/**
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user