mirror of
https://github.com/Telecominfraproject/wlan-cloud-owprov-ui.git
synced 2025-10-30 02:02:30 +00:00
[WIFI-11273] Added captive to services configuration
Signed-off-by: Charles <charles.bourque96@gmail.com>
This commit is contained in:
@@ -670,6 +670,7 @@
|
||||
"version": "Ausführung"
|
||||
},
|
||||
"form": {
|
||||
"captive_web_root_explanation": "Bitte verwenden Sie nur .tar-Dateien (keine komprimierten Dateien wie z. B. .targz)",
|
||||
"certificate_file_explanation": "Bitte verwenden Sie eine .pem-Datei, die mit „-----BEGIN CERTIFICATE-----“ beginnt und mit „-----END CERTIFICATE-----“ endet.",
|
||||
"invalid_cidr": "Ungültige CIDR-IPv4-Adresse. Beispiel: 192.168.0.1/12",
|
||||
"invalid_email": "Ungültige E-Mail",
|
||||
|
||||
@@ -670,6 +670,7 @@
|
||||
"version": "Version"
|
||||
},
|
||||
"form": {
|
||||
"captive_web_root_explanation": "Please use .tar files only (no compressed files like .targz, for example)",
|
||||
"certificate_file_explanation": "Please use a .pem file that starts with \"-----BEGIN CERTIFICATE-----\" and ends with \"-----END CERTIFICATE-----\"",
|
||||
"invalid_cidr": "Invalid CIDR IPv4 address. Example: 192.168.0.1/12",
|
||||
"invalid_email": "Invalid Email",
|
||||
|
||||
@@ -670,6 +670,7 @@
|
||||
"version": "Versión"
|
||||
},
|
||||
"form": {
|
||||
"captive_web_root_explanation": "Utilice únicamente archivos .tar (no archivos comprimidos como .targz, por ejemplo)",
|
||||
"certificate_file_explanation": "Utilice un archivo .pem que comience con \"-----BEGIN CERTIFICATE-----\" y termine con \"-----END CERTIFICATE-----\"",
|
||||
"invalid_cidr": "Dirección IPv4 CIDR no válida. Ejemplo: 192.168.0.1/12",
|
||||
"invalid_email": "Email inválido",
|
||||
|
||||
@@ -670,6 +670,7 @@
|
||||
"version": "Version"
|
||||
},
|
||||
"form": {
|
||||
"captive_web_root_explanation": "Veuillez utiliser uniquement des fichiers .tar (pas de fichiers compressés comme .targz, par exemple)",
|
||||
"certificate_file_explanation": "Veuillez utiliser un fichier .pem qui commence par \"-----BEGIN CERTIFICATE-----\" et se termine par \"-----END CERTIFICATE-----\"",
|
||||
"invalid_cidr": "Adresse IPv4 CIDR non valide. Exemple : 192.168.0.1/12",
|
||||
"invalid_email": "Email Invalide",
|
||||
|
||||
@@ -670,6 +670,7 @@
|
||||
"version": "Versão"
|
||||
},
|
||||
"form": {
|
||||
"captive_web_root_explanation": "Por favor, use apenas arquivos .tar (sem arquivos compactados como .targz, por exemplo)",
|
||||
"certificate_file_explanation": "Use um arquivo .pem que comece com \"-----BEGIN CERTIFICATE-----\" e termine com \"-----END CERTIFICATE-----\"",
|
||||
"invalid_cidr": "Endereço CIDR IPv4 inválido. Exemplo: 192.168.0.1/12",
|
||||
"invalid_email": "E-mail inválido",
|
||||
|
||||
@@ -10,6 +10,7 @@ interface Props {
|
||||
accept: string;
|
||||
isHidden?: boolean;
|
||||
isStringFile?: boolean;
|
||||
wantBase64?: boolean;
|
||||
}
|
||||
|
||||
const defaultProps = {
|
||||
@@ -18,7 +19,16 @@ const defaultProps = {
|
||||
isStringFile: false,
|
||||
};
|
||||
|
||||
const FileInputButton = ({ value, setValue, setFileName, refreshId, accept, isHidden, isStringFile }: Props) => {
|
||||
const FileInputButton = ({
|
||||
value,
|
||||
setValue,
|
||||
setFileName,
|
||||
refreshId,
|
||||
accept,
|
||||
isHidden,
|
||||
isStringFile,
|
||||
wantBase64,
|
||||
}: Props) => {
|
||||
const [fileKey, setFileKey] = useState(uuid());
|
||||
let fileReader: FileReader | undefined;
|
||||
|
||||
@@ -31,11 +41,27 @@ const FileInputButton = ({ value, setValue, setFileName, refreshId, accept, isHi
|
||||
}
|
||||
};
|
||||
|
||||
const handleBase64FileRead = () => {
|
||||
if (fileReader) {
|
||||
const content = fileReader.result;
|
||||
if (content && typeof content === 'string') {
|
||||
const split = content.split('base64,');
|
||||
if (split[1]) {
|
||||
setValue(split[1] as string);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const changeFile = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const file = e.target.files ? e.target.files[0] : undefined;
|
||||
if (file) {
|
||||
const newVal = URL.createObjectURL(file);
|
||||
if (!isStringFile) {
|
||||
if (wantBase64) {
|
||||
fileReader = new FileReader();
|
||||
fileReader.onloadend = handleBase64FileRead;
|
||||
fileReader.readAsDataURL(file);
|
||||
} else if (!isStringFile) {
|
||||
setValue(newVal, file);
|
||||
if (setFileName) setFileName(file.name ?? '');
|
||||
} else {
|
||||
|
||||
@@ -21,6 +21,7 @@ import PropTypes from 'prop-types';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
import ConfigurationFieldExplanation from '../ConfigurationFieldExplanation';
|
||||
import DeleteButton from 'components/Buttons/DeleteButton';
|
||||
import FileInputButton from 'components/Buttons/FileInputButton';
|
||||
import SaveButton from 'components/Buttons/SaveButton';
|
||||
import ModalHeader from 'components/Modals/ModalHeader';
|
||||
@@ -39,6 +40,9 @@ const propTypes = {
|
||||
error: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),
|
||||
touched: PropTypes.bool,
|
||||
definitionKey: PropTypes.string,
|
||||
canDelete: PropTypes.bool.isRequired,
|
||||
onDelete: PropTypes.func.isRequired,
|
||||
wantBase64: PropTypes.bool,
|
||||
};
|
||||
|
||||
const defaultProps = {
|
||||
@@ -51,6 +55,7 @@ const defaultProps = {
|
||||
error: false,
|
||||
touched: false,
|
||||
definitionKey: null,
|
||||
wantBase64: false,
|
||||
};
|
||||
|
||||
const FileInputModal = ({
|
||||
@@ -67,6 +72,9 @@ const FileInputModal = ({
|
||||
isDisabled,
|
||||
isHidden,
|
||||
definitionKey,
|
||||
canDelete,
|
||||
onDelete,
|
||||
wantBase64,
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const { isOpen, onOpen, onClose } = useDisclosure();
|
||||
@@ -108,9 +116,10 @@ const FileInputModal = ({
|
||||
onClick={onOpen}
|
||||
icon={<UploadSimple size={20} />}
|
||||
isDisabled={isDisabled}
|
||||
ml={2}
|
||||
mx={2}
|
||||
/>
|
||||
</Tooltip>
|
||||
{value !== undefined && canDelete && <DeleteButton onClick={onDelete} isCompact />}
|
||||
</Text>
|
||||
<FormErrorMessage>{error}</FormErrorMessage>
|
||||
</FormControl>
|
||||
@@ -135,7 +144,8 @@ const FileInputModal = ({
|
||||
setFileName={setTempFilename}
|
||||
refreshId={refreshId}
|
||||
accept={acceptedFileTypes}
|
||||
isStringFile
|
||||
isStringFile={!wantBase64}
|
||||
wantBase64={wantBase64}
|
||||
/>
|
||||
</Box>
|
||||
<FormControl isInvalid={tempValue !== '' && !test(tempValue)}>
|
||||
|
||||
@@ -14,6 +14,8 @@ const propTypes = {
|
||||
isRequired: PropTypes.bool,
|
||||
isHidden: PropTypes.bool,
|
||||
definitionKey: PropTypes.string,
|
||||
canDelete: PropTypes.bool,
|
||||
wantBase64: PropTypes.bool,
|
||||
};
|
||||
|
||||
const defaultProps = {
|
||||
@@ -22,6 +24,8 @@ const defaultProps = {
|
||||
isDisabled: false,
|
||||
isHidden: false,
|
||||
definitionKey: null,
|
||||
canDelete: false,
|
||||
wantBase64: false,
|
||||
};
|
||||
|
||||
const FileInputFieldModal = ({
|
||||
@@ -35,10 +39,16 @@ const FileInputFieldModal = ({
|
||||
isRequired,
|
||||
isHidden,
|
||||
definitionKey,
|
||||
canDelete,
|
||||
wantBase64,
|
||||
}) => {
|
||||
const [{ value }, { touched, error }, { setValue }] = useField(name);
|
||||
const [{ value: fileNameValue }, , { setValue: setFile }] = useField(fileName);
|
||||
|
||||
const onDelete = useCallback(() => {
|
||||
setValue(undefined);
|
||||
setFile(undefined);
|
||||
}, []);
|
||||
const onChange = useCallback((newValue, newFilename) => {
|
||||
setValue(newValue);
|
||||
setFile(newFilename);
|
||||
@@ -59,6 +69,9 @@ const FileInputFieldModal = ({
|
||||
isDisabled={isDisabled}
|
||||
isHidden={isHidden}
|
||||
definitionKey={definitionKey}
|
||||
canDelete={canDelete}
|
||||
onDelete={onDelete}
|
||||
wantBase64={wantBase64}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,182 @@
|
||||
import * as React from 'react';
|
||||
import { Box, Heading, Select, SimpleGrid, Spacer, VStack } from '@chakra-ui/react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { object, string } from 'yup';
|
||||
import Card from 'components/Card';
|
||||
import CardBody from 'components/Card/CardBody';
|
||||
import CardHeader from 'components/Card/CardHeader';
|
||||
import CreatableSelectField from 'components/FormFields/CreatableSelectField';
|
||||
import FileInputFieldModal from 'components/FormFields/FileInputFieldModal';
|
||||
import NumberField from 'components/FormFields/NumberField';
|
||||
import ObjectArrayFieldModal from 'components/FormFields/ObjectArrayFieldModal';
|
||||
import SelectField from 'components/FormFields/SelectField';
|
||||
import StringField from 'components/FormFields/StringField';
|
||||
import useFastField from 'hooks/useFastField';
|
||||
|
||||
const CREDENTIALS_SCHEMA = (t: (str: string) => string, useDefault = false) => {
|
||||
const shape = object().shape({
|
||||
username: string().required(t('form.required')).default(''),
|
||||
password: string().required(t('form.required')).default(''),
|
||||
});
|
||||
|
||||
return useDefault ? shape : shape.nullable().default(undefined);
|
||||
};
|
||||
const namePrefix = 'configuration.captive';
|
||||
|
||||
const CaptiveConfiguration = ({ editing }: { editing: boolean }) => {
|
||||
const { t } = useTranslation();
|
||||
const name = React.useCallback((suffix: string) => `${namePrefix}.${suffix}`, []);
|
||||
const { value: captive, onChange } = useFastField({
|
||||
name: namePrefix,
|
||||
});
|
||||
|
||||
const handleAuthModeChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
|
||||
if (e.target.value === 'radius') {
|
||||
onChange({
|
||||
'walled-garden-fqdn': [],
|
||||
'idle-timeout': 600,
|
||||
'auth-mode': e.target.value,
|
||||
'auth-server': '192.168.1.10',
|
||||
'auth-secret': 'secret',
|
||||
'aut-port': 1812,
|
||||
});
|
||||
} else if (e.target.value === 'uam') {
|
||||
onChange({
|
||||
'walled-garden-fqdn': [],
|
||||
'idle-timeout': 600,
|
||||
'auth-mode': e.target.value,
|
||||
'auth-server': '192.168.1.10',
|
||||
'auth-secret': 'secret',
|
||||
'aut-port': 1812,
|
||||
'uam-port': 3990,
|
||||
'uam-secret': 'secret',
|
||||
'uam-server': 'https://YOUR-LOGIN-ADDRESS.YOURS',
|
||||
nasid: 'TestLab',
|
||||
});
|
||||
} else {
|
||||
onChange({ 'walled-garden-fqdn': [], 'idle-timeout': 600, 'auth-mode': e.target.value });
|
||||
}
|
||||
};
|
||||
|
||||
const fieldProps = (suffix: string) => ({
|
||||
name: name(suffix),
|
||||
label: suffix,
|
||||
definitionKey: `interface.ssid.pass-point.${suffix}`,
|
||||
isDisabled: !editing,
|
||||
});
|
||||
|
||||
const mode = captive?.['auth-mode'] as string | undefined;
|
||||
|
||||
const credFields = React.useMemo(
|
||||
() => (
|
||||
<SimpleGrid minChildWidth="300px" gap={4}>
|
||||
<StringField name="username" label="username" isRequired />
|
||||
<StringField name="password" label="password" isRequired />
|
||||
</SimpleGrid>
|
||||
),
|
||||
[],
|
||||
);
|
||||
const credCols = React.useMemo(
|
||||
() => [
|
||||
{
|
||||
id: 'username',
|
||||
Header: 'username',
|
||||
Footer: '',
|
||||
accessor: 'username',
|
||||
},
|
||||
{
|
||||
id: 'password',
|
||||
Header: 'password',
|
||||
Footer: '',
|
||||
accessor: 'password',
|
||||
},
|
||||
],
|
||||
[],
|
||||
);
|
||||
|
||||
return (
|
||||
<Card variant="widget" mb={4}>
|
||||
<CardHeader>
|
||||
<Heading my="auto" size="md" textDecor="underline">
|
||||
Captive
|
||||
</Heading>
|
||||
<Spacer />
|
||||
<Box>
|
||||
<Select value={captive['auth-mode']} onChange={handleAuthModeChange} isDisabled={!editing}>
|
||||
<option value="click">Click</option>
|
||||
<option value="radius">Radius</option>
|
||||
<option value="credentials">Credentials</option>
|
||||
<option value="uam">UAM</option>
|
||||
</Select>
|
||||
</Box>
|
||||
</CardHeader>
|
||||
<CardBody pb={8} pt={2} display="block">
|
||||
{
|
||||
// Basic Fields
|
||||
}
|
||||
<VStack spacing={2}>
|
||||
<CreatableSelectField {...fieldProps('walled-garden-fqdn')} placeholder="Example: *.google.com" isRequired />
|
||||
<FileInputFieldModal
|
||||
{...fieldProps('web-root')}
|
||||
fileName="configuration.captive.web-root-filename"
|
||||
definitionKey="service.captive.web-root"
|
||||
explanation={t('form.captive_web_root_explanation')}
|
||||
test={() => true}
|
||||
acceptedFileTypes=".tar"
|
||||
isDisabled={!editing}
|
||||
canDelete
|
||||
isRequired
|
||||
wantBase64
|
||||
/>
|
||||
<NumberField {...fieldProps('idle-timeout')} isRequired w="100px" />
|
||||
<NumberField {...fieldProps('session-timeout')} emptyIsUndefined acceptEmptyValue w="100px" />
|
||||
{mode === 'credentials' && (
|
||||
<ObjectArrayFieldModal
|
||||
{...fieldProps('credentials')}
|
||||
fields={credFields}
|
||||
columns={credCols}
|
||||
schema={CREDENTIALS_SCHEMA}
|
||||
isDisabled={!editing}
|
||||
isRequired
|
||||
/>
|
||||
)}
|
||||
</VStack>
|
||||
{mode === 'uam' && (
|
||||
<VStack spacing={2}>
|
||||
<StringField {...fieldProps('uam-server')} isRequired />
|
||||
<StringField {...fieldProps('uam-secret')} isRequired hideButton />
|
||||
<NumberField {...fieldProps('uam-port')} isRequired />
|
||||
<StringField {...fieldProps('nasid')} isRequired />
|
||||
<StringField {...fieldProps('nasmac')} />
|
||||
<SelectField
|
||||
{...fieldProps('mac-format')}
|
||||
options={[
|
||||
{ value: 'aabbccddeeff', label: 'aabbccddeeff' },
|
||||
{ value: 'aa-bb-cc-dd-ee-ff', label: 'aa-bb-cc-dd-ee-ff' },
|
||||
{ value: 'aa:bb:cc:dd:ee:ff', label: 'aa:bb:cc:dd:ee:ff' },
|
||||
{ value: 'AABBCCDDEEFF', label: 'AABBCCDDEEFF' },
|
||||
{ value: 'AA:BB:CC:DD:EE:FF', label: 'AA:BB:CC:DD:EE:FF' },
|
||||
{ value: 'AA-BB-CC-DD-EE-FF', label: 'AA-BB-CC-DD-EE-FF' },
|
||||
]}
|
||||
isRequired
|
||||
/>
|
||||
<StringField {...fieldProps('ssid')} />
|
||||
</VStack>
|
||||
)}
|
||||
{(mode === 'radius' || mode === 'uam') && (
|
||||
<VStack spacing={2}>
|
||||
<StringField {...fieldProps('auth-server')} isRequired />
|
||||
<StringField {...fieldProps('auth-secret')} isRequired hideButton />
|
||||
<NumberField {...fieldProps('auth-port')} isRequired />
|
||||
<StringField {...fieldProps('acct-server')} emptyIsUndefined />
|
||||
<StringField {...fieldProps('acct-secret')} emptyIsUndefined hideButton />
|
||||
<NumberField {...fieldProps('acct-port')} emptyIsUndefined acceptEmptyValue />
|
||||
<NumberField {...fieldProps('acct-interval')} emptyIsUndefined acceptEmptyValue />
|
||||
</VStack>
|
||||
)}
|
||||
</CardBody>
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
|
||||
export default React.memo(CaptiveConfiguration);
|
||||
@@ -9,6 +9,7 @@ import InternalFormAccess from '../common/InternalFormAccess';
|
||||
import SectionGeneralCard from '../common/SectionGeneralCard';
|
||||
import SubSectionPicker from '../common/SubSectionPicker';
|
||||
import AirtimePolicies from './AirtimePolicies';
|
||||
import Captive from './Captive';
|
||||
import DataPlane from './DataPlane';
|
||||
import FacebookWifi from './FacebookWifi';
|
||||
import Http from './Http';
|
||||
@@ -121,6 +122,7 @@ const ServicesSection = ({ editing, setSection, sectionInformation, removeSub })
|
||||
editing={editing}
|
||||
subsections={[
|
||||
'airtime-policies',
|
||||
'captive',
|
||||
'data-plane',
|
||||
'facebook-wifi',
|
||||
'http',
|
||||
@@ -159,6 +161,7 @@ const ServicesSection = ({ editing, setSection, sectionInformation, removeSub })
|
||||
{isSubSectionActive('data-plane') && <DataPlane editing={editing} />}
|
||||
{isSubSectionActive('ieee8021x') && <Ieee8021x editing={editing} />}
|
||||
{isSubSectionActive('radius-proxy') && <RadiusProxy editing={editing} />}
|
||||
{isSubSectionActive('captive') && <Captive editing={editing} />}
|
||||
</Masonry>
|
||||
</>
|
||||
)}
|
||||
|
||||
@@ -1,6 +1,125 @@
|
||||
import { object, number, string, array, bool } from 'yup';
|
||||
import { testFqdnHostname, testIpv4, testLength, testUcMac } from 'constants/formTests';
|
||||
|
||||
export const SERVICES_CAPTIVE_SCHEMA = (t, useDefault = false) => {
|
||||
const shape = object()
|
||||
.shape({
|
||||
'auto-mode': string().required(t('form.required')).default('click'),
|
||||
'walled-garden-fqdn': array().of(string()).min(1, t('form.required')).default([]),
|
||||
'web-root': string().default(undefined),
|
||||
'idle-timeout': number().required(t('form.required')).positive().lessThan(65535).integer().default(600),
|
||||
'session-timeout': number().positive().lessThan(65535).integer().default(undefined),
|
||||
// Only if auto-mode is "credentials"
|
||||
credentials: array()
|
||||
.when('auth-mode', {
|
||||
is: 'credentials',
|
||||
then: array()
|
||||
.of(
|
||||
object().shape({
|
||||
username: string().required(t('form.required')).default(''),
|
||||
password: string().required(t('form.required')).default(''),
|
||||
}),
|
||||
)
|
||||
.min(1, t('form.required')),
|
||||
})
|
||||
.default(undefined),
|
||||
// Radius && UAM values
|
||||
'auth-server': string()
|
||||
.when('auth-mode', {
|
||||
is: (authMode) => authMode === 'radius' || authMode === 'uam',
|
||||
then: string().required(t('form.required')).default(''),
|
||||
})
|
||||
.default(undefined),
|
||||
'auth-secret': string()
|
||||
.when('auth-mode', {
|
||||
is: (authMode) => authMode === 'radius' || authMode === 'uam',
|
||||
then: string().required(t('form.required')).default(''),
|
||||
else: string().default(undefined),
|
||||
})
|
||||
.default(undefined),
|
||||
'auth-port': number()
|
||||
.when('auth-mode', {
|
||||
is: (authMode) => authMode === 'radius' || authMode === 'uam',
|
||||
then: number().required(t('form.required')).moreThan(1023).lessThan(65535).integer().default(1812),
|
||||
else: number().default(undefined),
|
||||
})
|
||||
.default(undefined),
|
||||
'acct-server': string()
|
||||
.when('auth-mode', {
|
||||
is: (authMode) => authMode === 'radius' || authMode === 'uam',
|
||||
then: string().default(undefined),
|
||||
else: string().default(undefined),
|
||||
})
|
||||
.default(undefined),
|
||||
'acct-secret': string()
|
||||
.when('auth-mode', {
|
||||
is: (authMode) => authMode === 'radius' || authMode === 'uam',
|
||||
then: string().default(undefined),
|
||||
else: string().default(undefined),
|
||||
})
|
||||
.default(undefined),
|
||||
'acct-port': number()
|
||||
.when('auth-mode', {
|
||||
is: (authMode) => authMode === 'radius' || authMode === 'uam',
|
||||
then: number().moreThan(1023).lessThan(65535).integer().default(undefined),
|
||||
else: number().default(undefined),
|
||||
})
|
||||
.default(undefined),
|
||||
'acct-interval': number()
|
||||
.when('auth-mode', {
|
||||
is: (authMode) => authMode === 'radius' || authMode === 'uam',
|
||||
then: number().positive().lessThan(65535).integer().default(undefined),
|
||||
})
|
||||
.default(undefined),
|
||||
// Only UAM fields
|
||||
'uam-server': string()
|
||||
.when('auth-mode', {
|
||||
is: (authMode) => authMode === 'uam',
|
||||
then: string().required(t('form.required')).default(''),
|
||||
})
|
||||
.default(undefined),
|
||||
'uam-secret': string()
|
||||
.when('auth-mode', {
|
||||
is: (authMode) => authMode === 'uam',
|
||||
then: string().required(t('form.required')).default(''),
|
||||
})
|
||||
.default(undefined),
|
||||
'uam-port': number()
|
||||
.when('auth-mode', {
|
||||
is: (authMode) => authMode === 'uam',
|
||||
then: number().required(t('form.required')).moreThan(1023).lessThan(65535).integer().default(3990),
|
||||
})
|
||||
.default(undefined),
|
||||
ssid: string()
|
||||
.when('auth-mode', {
|
||||
is: (authMode) => authMode === 'uam',
|
||||
then: string().default(undefined),
|
||||
})
|
||||
.default(undefined),
|
||||
'mac-format': string()
|
||||
.when('auth-mode', {
|
||||
is: (authMode) => authMode === 'uam',
|
||||
then: string().required(t('form.required')).default('aabbccddeeff'),
|
||||
})
|
||||
.default(undefined),
|
||||
nasid: string()
|
||||
.when('auth-mode', {
|
||||
is: (authMode) => authMode === 'uam',
|
||||
then: string().required(t('form.required')).default(''),
|
||||
})
|
||||
.default(undefined),
|
||||
nasmac: string()
|
||||
.when('auth-mode', {
|
||||
is: (authMode) => authMode === 'uam',
|
||||
then: string().default(undefined),
|
||||
})
|
||||
.default(undefined),
|
||||
})
|
||||
.default({});
|
||||
|
||||
return useDefault ? shape : shape.nullable().default(undefined);
|
||||
};
|
||||
|
||||
export const SERVICES_CLASSIFIER_DNS_SCHEMA = (t, useDefault = false) => {
|
||||
const shape = object().shape({
|
||||
fqdn: string().default(''),
|
||||
@@ -295,6 +414,7 @@ export const SERVICES_SCHEMA = (t, useDefault = false) =>
|
||||
'data-plane': SERVICES_DATA_PLANE_SCHEMA(t, useDefault),
|
||||
'radius-proxy': SERVICES_RADIUS_PROXY_SCHEMA(t, useDefault),
|
||||
ieee8021x: SERVICES_IEEE8021X_SCHEMA(t, useDefault),
|
||||
captive: SERVICES_CAPTIVE_SCHEMA(t, useDefault),
|
||||
}),
|
||||
});
|
||||
|
||||
@@ -334,6 +454,8 @@ export const getSubSectionDefaults = (t, sub) => {
|
||||
return SERVICES_IEEE8021X_SCHEMA(t, true).cast();
|
||||
case 'radius-proxy':
|
||||
return SERVICES_RADIUS_PROXY_SCHEMA(t, true).cast();
|
||||
case 'captive':
|
||||
return SERVICES_CAPTIVE_SCHEMA(t, true).cast();
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user