0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2025-01-20 21:32:31 -05:00

refactor(console): show sso status in jit domains (#6040)

This commit is contained in:
Gao Sun 2024-06-18 10:00:35 +08:00 committed by GitHub
parent d9119b56ec
commit c2c15e8bcf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 52 additions and 8 deletions

View file

@ -4,6 +4,11 @@
margin-top: _.unit(3);
}
.ssoEnabled {
vertical-align: middle;
color: var(--color-text-link);
}
.warning {
margin-top: _.unit(3);
}

View file

@ -1,12 +1,14 @@
import { type SignInExperience, type Organization } from '@logto/schemas';
import { type SignInExperience, type Organization, type SsoConnector } from '@logto/schemas';
import { trySafe } from '@silverhand/essentials';
import { useState } from 'react';
import { useState, useCallback } from 'react';
import { Controller, useForm } from 'react-hook-form';
import { toast } from 'react-hot-toast';
import { useTranslation } from 'react-i18next';
import { Trans, useTranslation } from 'react-i18next';
import { useOutletContext } from 'react-router-dom';
import useSWR from 'swr';
import useSWRInfinite from 'swr/infinite';
import SsoIcon from '@/assets/icons/single-sign-on.svg';
import DetailsForm from '@/components/DetailsForm';
import FormCard from '@/components/FormCard';
import MultiOptionInput from '@/components/MultiOptionInput';
@ -82,6 +84,21 @@ function Settings() {
const [isJitEnabled, isMfaRequired] = watch(['isJitEnabled', 'isMfaRequired']);
const api = useApi();
const [keyword, setKeyword] = useState('');
// Fetch all SSO connector to show if a domain is configured SSO
const { data: ssoConnectors } = useSWRInfinite<SsoConnector[]>(
(index, previous) => {
return previous && previous.length === 0 ? null : `api/sso-connectors?page=${index + 1}`;
},
{ initialSize: Number.POSITIVE_INFINITY }
);
const hasSsoEnabled = useCallback(
(domain: string) =>
ssoConnectors?.some((connectors) =>
connectors.some(({ domains }) => domains.includes(domain))
),
[ssoConnectors]
);
const onSubmit = handleSubmit(
trySubmitSafe(async (data) => {
@ -167,14 +184,34 @@ function Settings() {
</div>
</FormField>
{isJitEnabled && (
<FormField title="organization_details.jit.email_domains">
<FormField
title="organization_details.jit.email_domains"
description={
<Trans
components={{
Icon: <SsoIcon className={styles.ssoEnabled} />,
}}
>
{t('organization_details.jit.sso_email_domain_description')}
</Trans>
}
>
<Controller
name="jitEmailDomains"
control={control}
render={({ field: { onChange, value } }) => (
<MultiOptionInput
values={value}
renderValue={(value) => value}
renderValue={(value) =>
hasSsoEnabled(value) ? (
<>
<SsoIcon className={styles.ssoEnabled} />
{value}
</>
) : (
value
)
}
validateInput={(input) => {
if (!domainRegExp.test(input)) {
return t('organization_details.jit.invalid_domain');

View file

@ -9,10 +9,10 @@ const enterprise_sso_details = {
custom_branding_title: 'Display',
custom_branding_description:
"Customize the name and logo displayed in the end users' Single Sign-On flow. When empty, defaults are used.",
email_domain_field_name: 'Enterprise email domain',
email_domain_field_name: 'Enterprise email domains',
email_domain_field_description:
'Users with this email domain can use SSO for authentication. Please verify the domain belongs to the enterprise.',
email_domain_field_placeholder: 'Email domain',
'Users with these email domains can use SSO for authentication. Please verify the domain ownership before adding.',
email_domain_field_placeholder: 'Enter one or more email domains (e.g. yourcompany.com)',
sync_profile_field_name: 'Sync profile information from the identity provider',
sync_profile_option: {
register_only: 'Only sync at first sign-in',

View file

@ -36,6 +36,8 @@ const organization_details = {
email_domains: 'JIT provisioning email domains',
email_domains_placeholder: 'Enter email domains for just-in-time provisioning',
invalid_domain: 'Invalid domain',
sso_email_domain_description:
'<Icon /> means the domain is enabled for enterprise SSO. Users who signed in through the configured IdP can automatically join the organization.',
domain_already_added: 'Domain already added',
organization_roles: 'Default organization roles',
organization_roles_description: