mirror of
https://github.com/n8n-io/n8n.git
synced 2025-03-05 20:50:17 -08:00
feat(editor): SAML paywall state (#5906)
* feat(editor): SAML paywall state * fix(editor): fix translation * fix(editor): SSO update links
This commit is contained in:
parent
07c360c30d
commit
d40e86aabc
|
@ -1736,6 +1736,9 @@
|
||||||
"settings.sso.settings.ips.help": "Add the raw Metadata XML provided by your Identity Provider",
|
"settings.sso.settings.ips.help": "Add the raw Metadata XML provided by your Identity Provider",
|
||||||
"settings.sso.settings.test": "Test settings",
|
"settings.sso.settings.test": "Test settings",
|
||||||
"settings.sso.settings.save": "Save settings",
|
"settings.sso.settings.save": "Save settings",
|
||||||
|
"settings.sso.actionBox.title": "Available on Enterprise plan",
|
||||||
|
"settings.sso.actionBox.description": "Use Single Sign On to consolidate authentication into a single platform to improve security and agility.",
|
||||||
|
"settings.sso.actionBox.buttonText": "See plans",
|
||||||
"sso.login.divider": "or",
|
"sso.login.divider": "or",
|
||||||
"sso.login.button": "Continue with SSO"
|
"sso.login.button": "Continue with SSO"
|
||||||
}
|
}
|
||||||
|
|
|
@ -578,12 +578,7 @@ export const routes = [
|
||||||
deny: {
|
deny: {
|
||||||
shouldDeny: () => {
|
shouldDeny: () => {
|
||||||
const settingsStore = useSettingsStore();
|
const settingsStore = useSettingsStore();
|
||||||
const ssoStore = useSSOStore();
|
return settingsStore.isCloudDeployment || settingsStore.isDesktopDeployment;
|
||||||
return (
|
|
||||||
!ssoStore.isEnterpriseSamlEnabled ||
|
|
||||||
settingsStore.isCloudDeployment ||
|
|
||||||
settingsStore.isDesktopDeployment
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -2,10 +2,14 @@
|
||||||
import { computed, ref, onBeforeMount } from 'vue';
|
import { computed, ref, onBeforeMount } from 'vue';
|
||||||
import { Notification } from 'element-ui';
|
import { Notification } from 'element-ui';
|
||||||
import { useSSOStore } from '@/stores/sso';
|
import { useSSOStore } from '@/stores/sso';
|
||||||
import { i18n as locale } from '@/plugins/i18n';
|
import { useUsageStore } from '@/stores/usage';
|
||||||
|
import { useUIStore } from '@/stores/ui';
|
||||||
|
import { BaseTextKey, i18n as locale } from '@/plugins/i18n';
|
||||||
import CopyInput from '@/components/CopyInput.vue';
|
import CopyInput from '@/components/CopyInput.vue';
|
||||||
|
|
||||||
const ssoStore = useSSOStore();
|
const ssoStore = useSSOStore();
|
||||||
|
const usageStore = useUsageStore();
|
||||||
|
const uiStore = useUIStore();
|
||||||
|
|
||||||
const ssoActivatedLabel = computed(() =>
|
const ssoActivatedLabel = computed(() =>
|
||||||
ssoStore.isSamlLoginEnabled
|
ssoStore.isSamlLoginEnabled
|
||||||
|
@ -51,7 +55,23 @@ const onTest = async () => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const goToUpgrade = () => {
|
||||||
|
const linkUrlTranslationKey = uiStore.contextBasedTranslationKeys.upgradeLinkUrl as BaseTextKey;
|
||||||
|
let linkUrl = locale.baseText(linkUrlTranslationKey);
|
||||||
|
|
||||||
|
if (linkUrlTranslationKey.endsWith('.upgradeLinkUrl')) {
|
||||||
|
linkUrl = `${usageStore.viewPlansUrl}&source=sso`;
|
||||||
|
} else if (linkUrlTranslationKey.endsWith('.desktop')) {
|
||||||
|
linkUrl = `${linkUrl}&utm_campaign=upgrade-sso`;
|
||||||
|
}
|
||||||
|
|
||||||
|
window.open(linkUrl, '_blank');
|
||||||
|
};
|
||||||
|
|
||||||
onBeforeMount(async () => {
|
onBeforeMount(async () => {
|
||||||
|
if (!ssoStore.isEnterpriseSamlEnabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
await getSamlConfig();
|
await getSamlConfig();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
@ -69,7 +89,7 @@ onBeforeMount(async () => {
|
||||||
<n8n-heading size="2xlarge">{{ locale.baseText('settings.sso.title') }}</n8n-heading>
|
<n8n-heading size="2xlarge">{{ locale.baseText('settings.sso.title') }}</n8n-heading>
|
||||||
<div :class="$style.top">
|
<div :class="$style.top">
|
||||||
<n8n-heading size="medium">{{ locale.baseText('settings.sso.subtitle') }}</n8n-heading>
|
<n8n-heading size="medium">{{ locale.baseText('settings.sso.subtitle') }}</n8n-heading>
|
||||||
<n8n-tooltip :disabled="ssoStore.isSamlLoginEnabled">
|
<n8n-tooltip v-if="ssoStore.isEnterpriseSamlEnabled" :disabled="ssoStore.isSamlLoginEnabled">
|
||||||
<template #content>
|
<template #content>
|
||||||
<span>
|
<span>
|
||||||
{{ locale.baseText('settings.sso.activation.tooltip') }}
|
{{ locale.baseText('settings.sso.activation.tooltip') }}
|
||||||
|
@ -86,45 +106,58 @@ onBeforeMount(async () => {
|
||||||
<n8n-info-tip>
|
<n8n-info-tip>
|
||||||
<i18n :class="$style.count" path="settings.sso.info">
|
<i18n :class="$style.count" path="settings.sso.info">
|
||||||
<template #link>
|
<template #link>
|
||||||
<a href="https://docs.n8n.io/user-management/sso/" target="_blank">
|
<a href="https://docs.n8n.io/user-management/saml/" target="_blank">
|
||||||
{{ locale.baseText('settings.sso.info.link') }}
|
{{ locale.baseText('settings.sso.info.link') }}
|
||||||
</a>
|
</a>
|
||||||
</template>
|
</template>
|
||||||
</i18n>
|
</i18n>
|
||||||
</n8n-info-tip>
|
</n8n-info-tip>
|
||||||
<div :class="$style.group">
|
<div v-if="ssoStore.isEnterpriseSamlEnabled">
|
||||||
<label>{{ locale.baseText('settings.sso.settings.redirectUrl.label') }}</label>
|
<div :class="$style.group">
|
||||||
<CopyInput
|
<label>{{ locale.baseText('settings.sso.settings.redirectUrl.label') }}</label>
|
||||||
:class="$style.copyInput"
|
<CopyInput
|
||||||
:value="redirectUrl"
|
:class="$style.copyInput"
|
||||||
:copy-button-text="locale.baseText('generic.clickToCopy')"
|
:value="redirectUrl"
|
||||||
:toast-title="locale.baseText('settings.sso.settings.redirectUrl.copied')"
|
:copy-button-text="locale.baseText('generic.clickToCopy')"
|
||||||
/>
|
:toast-title="locale.baseText('settings.sso.settings.redirectUrl.copied')"
|
||||||
<small>{{ locale.baseText('settings.sso.settings.redirectUrl.help') }}</small>
|
/>
|
||||||
</div>
|
<small>{{ locale.baseText('settings.sso.settings.redirectUrl.help') }}</small>
|
||||||
<div :class="$style.group">
|
</div>
|
||||||
<label>{{ locale.baseText('settings.sso.settings.entityId.label') }}</label>
|
<div :class="$style.group">
|
||||||
<CopyInput
|
<label>{{ locale.baseText('settings.sso.settings.entityId.label') }}</label>
|
||||||
:class="$style.copyInput"
|
<CopyInput
|
||||||
:value="entityId"
|
:class="$style.copyInput"
|
||||||
:copy-button-text="locale.baseText('generic.clickToCopy')"
|
:value="entityId"
|
||||||
:toast-title="locale.baseText('settings.sso.settings.entityId.copied')"
|
:copy-button-text="locale.baseText('generic.clickToCopy')"
|
||||||
/>
|
:toast-title="locale.baseText('settings.sso.settings.entityId.copied')"
|
||||||
<small>{{ locale.baseText('settings.sso.settings.entityId.help') }}</small>
|
/>
|
||||||
</div>
|
<small>{{ locale.baseText('settings.sso.settings.entityId.help') }}</small>
|
||||||
<div :class="$style.group">
|
</div>
|
||||||
<label>{{ locale.baseText('settings.sso.settings.ips.label') }}</label>
|
<div :class="$style.group">
|
||||||
<n8n-input v-model="metadata" type="textarea" />
|
<label>{{ locale.baseText('settings.sso.settings.ips.label') }}</label>
|
||||||
<small>{{ locale.baseText('settings.sso.settings.ips.help') }}</small>
|
<n8n-input v-model="metadata" type="textarea" />
|
||||||
</div>
|
<small>{{ locale.baseText('settings.sso.settings.ips.help') }}</small>
|
||||||
<div :class="$style.buttons">
|
</div>
|
||||||
<n8n-button :disabled="!ssoSettingsSaved" type="tertiary" @click="onTest">
|
<div :class="$style.buttons">
|
||||||
{{ locale.baseText('settings.sso.settings.test') }}
|
<n8n-button :disabled="!ssoSettingsSaved" type="tertiary" @click="onTest">
|
||||||
</n8n-button>
|
{{ locale.baseText('settings.sso.settings.test') }}
|
||||||
<n8n-button :disabled="!metadata" @click="onSave">
|
</n8n-button>
|
||||||
{{ locale.baseText('settings.sso.settings.save') }}
|
<n8n-button :disabled="!metadata" @click="onSave">
|
||||||
</n8n-button>
|
{{ locale.baseText('settings.sso.settings.save') }}
|
||||||
|
</n8n-button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<n8n-action-box
|
||||||
|
v-else
|
||||||
|
:class="$style.actionBox"
|
||||||
|
:description="locale.baseText('settings.sso.actionBox.description')"
|
||||||
|
:buttonText="locale.baseText('settings.sso.actionBox.buttonText')"
|
||||||
|
@click="goToUpgrade"
|
||||||
|
>
|
||||||
|
<template #heading>
|
||||||
|
<span>{{ locale.baseText('settings.sso.actionBox.title') }}</span>
|
||||||
|
</template>
|
||||||
|
</n8n-action-box>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -171,4 +204,8 @@ onBeforeMount(async () => {
|
||||||
color: var(--color-text-base);
|
color: var(--color-text-base);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.actionBox {
|
||||||
|
margin: var(--spacing-2xl) 0 0;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
Loading…
Reference in a new issue