mirror of
https://github.com/Unleash/unleash.git
synced 2025-05-08 01:15:49 +02:00
feat: scim assume control UI - move scim into sso configs (#6929)
- Adds support for the configuration option for SCIM taking over control of users and groups - Moves SCIM settings into SSO config pages (OIDC and SAML). SCIM registers a callback to be invoked when saving in a parent SSO config page
This commit is contained in:
parent
19055b1e33
commit
d1bb65bebd
@ -11,15 +11,11 @@ import { ADMIN } from '@server/types/permissions';
|
|||||||
import { PremiumFeature } from 'component/common/PremiumFeature/PremiumFeature';
|
import { PremiumFeature } from 'component/common/PremiumFeature/PremiumFeature';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { TabPanel } from 'component/common/TabNav/TabPanel/TabPanel';
|
import { TabPanel } from 'component/common/TabNav/TabPanel/TabPanel';
|
||||||
import { useUiFlag } from 'hooks/useUiFlag';
|
|
||||||
import { ScimSettings } from './ScimSettings/ScimSettings';
|
|
||||||
|
|
||||||
export const AuthSettings = () => {
|
export const AuthSettings = () => {
|
||||||
const { authenticationType } = useUiConfig().uiConfig;
|
const { authenticationType } = useUiConfig().uiConfig;
|
||||||
const { uiConfig } = useUiConfig();
|
const { uiConfig } = useUiConfig();
|
||||||
|
|
||||||
const scimEnabled = useUiFlag('scimApi');
|
|
||||||
|
|
||||||
const tabs = [
|
const tabs = [
|
||||||
{
|
{
|
||||||
label: 'OpenID Connect',
|
label: 'OpenID Connect',
|
||||||
@ -41,13 +37,6 @@ export const AuthSettings = () => {
|
|||||||
(item) => uiConfig.flags?.googleAuthEnabled || item.label !== 'Google',
|
(item) => uiConfig.flags?.googleAuthEnabled || item.label !== 'Google',
|
||||||
);
|
);
|
||||||
|
|
||||||
if (scimEnabled) {
|
|
||||||
tabs.push({
|
|
||||||
label: 'Provisioning (SCIM)',
|
|
||||||
component: <ScimSettings />,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const [activeTab, setActiveTab] = useState(0);
|
const [activeTab, setActiveTab] = useState(0);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -21,6 +21,10 @@ import { formatUnknownError } from 'utils/formatUnknownError';
|
|||||||
import { removeEmptyStringFields } from 'utils/removeEmptyStringFields';
|
import { removeEmptyStringFields } from 'utils/removeEmptyStringFields';
|
||||||
import { SsoGroupSettings } from '../SsoGroupSettings';
|
import { SsoGroupSettings } from '../SsoGroupSettings';
|
||||||
import type { IRole } from 'interfaces/role';
|
import type { IRole } from 'interfaces/role';
|
||||||
|
import { useUiFlag } from 'hooks/useUiFlag';
|
||||||
|
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||||
|
import { useScim } from 'hooks/useScim';
|
||||||
|
import { ScimConfigSettings } from '../ScimSettings/ScimSettings';
|
||||||
|
|
||||||
const initialState = {
|
const initialState = {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
@ -85,6 +89,22 @@ export const OidcAuth = () => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const {
|
||||||
|
settings,
|
||||||
|
enabled,
|
||||||
|
setEnabled,
|
||||||
|
assumeControlOfExisting,
|
||||||
|
setAssumeControlOfExisting,
|
||||||
|
newToken,
|
||||||
|
tokenGenerationDialog,
|
||||||
|
setTokenGenerationDialog,
|
||||||
|
tokenDialog,
|
||||||
|
setTokenDialog,
|
||||||
|
loading: scimLoading,
|
||||||
|
saveScimSettings,
|
||||||
|
onGenerateNewTokenConfirm,
|
||||||
|
} = useScim();
|
||||||
|
|
||||||
const onSubmit = async (event: React.SyntheticEvent) => {
|
const onSubmit = async (event: React.SyntheticEvent) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
@ -94,11 +114,14 @@ export const OidcAuth = () => {
|
|||||||
title: 'Settings stored',
|
title: 'Settings stored',
|
||||||
type: 'success',
|
type: 'success',
|
||||||
});
|
});
|
||||||
|
saveScimSettings();
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
setToastApiError(formatUnknownError(error));
|
setToastApiError(formatUnknownError(error));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const scimEnabled = useUiFlag('scimApi');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Grid container sx={{ mb: 3 }}>
|
<Grid container sx={{ mb: 3 }}>
|
||||||
@ -255,6 +278,32 @@ export const OidcAuth = () => {
|
|||||||
data={data}
|
data={data}
|
||||||
setValue={setValue}
|
setValue={setValue}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<ConditionallyRender
|
||||||
|
condition={scimEnabled}
|
||||||
|
show={
|
||||||
|
<ScimConfigSettings
|
||||||
|
disabled={!data.enabled}
|
||||||
|
settings={settings}
|
||||||
|
enabled={enabled}
|
||||||
|
setEnabled={setEnabled}
|
||||||
|
assumeControlOfExisting={assumeControlOfExisting}
|
||||||
|
setAssumeControlOfExisting={
|
||||||
|
setAssumeControlOfExisting
|
||||||
|
}
|
||||||
|
newToken={newToken}
|
||||||
|
tokenGenerationDialog={tokenGenerationDialog}
|
||||||
|
setTokenGenerationDialog={setTokenGenerationDialog}
|
||||||
|
tokenDialog={tokenDialog}
|
||||||
|
setTokenDialog={setTokenDialog}
|
||||||
|
loading={scimLoading}
|
||||||
|
onGenerateNewTokenConfirm={
|
||||||
|
onGenerateNewTokenConfirm
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
|
||||||
<AutoCreateForm
|
<AutoCreateForm
|
||||||
data={data}
|
data={data}
|
||||||
setValue={setValue}
|
setValue={setValue}
|
||||||
@ -296,6 +345,7 @@ export const OidcAuth = () => {
|
|||||||
</FormControl>
|
</FormControl>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<Grid container spacing={3}>
|
<Grid container spacing={3}>
|
||||||
<Grid item md={12}>
|
<Grid item md={12}>
|
||||||
<Button
|
<Button
|
||||||
|
@ -17,6 +17,10 @@ import { formatUnknownError } from 'utils/formatUnknownError';
|
|||||||
import { removeEmptyStringFields } from 'utils/removeEmptyStringFields';
|
import { removeEmptyStringFields } from 'utils/removeEmptyStringFields';
|
||||||
import { SsoGroupSettings } from '../SsoGroupSettings';
|
import { SsoGroupSettings } from '../SsoGroupSettings';
|
||||||
import type { IRole } from 'interfaces/role';
|
import type { IRole } from 'interfaces/role';
|
||||||
|
import { useUiFlag } from 'hooks/useUiFlag';
|
||||||
|
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||||
|
import { useScim } from 'hooks/useScim';
|
||||||
|
import { ScimConfigSettings } from '../ScimSettings/ScimSettings';
|
||||||
|
|
||||||
const initialState = {
|
const initialState = {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
@ -76,6 +80,22 @@ export const SamlAuth = () => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const {
|
||||||
|
settings,
|
||||||
|
enabled,
|
||||||
|
setEnabled,
|
||||||
|
assumeControlOfExisting,
|
||||||
|
setAssumeControlOfExisting,
|
||||||
|
newToken,
|
||||||
|
tokenGenerationDialog,
|
||||||
|
setTokenGenerationDialog,
|
||||||
|
tokenDialog,
|
||||||
|
setTokenDialog,
|
||||||
|
loading: scimLoading,
|
||||||
|
saveScimSettings,
|
||||||
|
onGenerateNewTokenConfirm,
|
||||||
|
} = useScim();
|
||||||
|
|
||||||
const onSubmit = async (event: React.SyntheticEvent) => {
|
const onSubmit = async (event: React.SyntheticEvent) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
@ -85,11 +105,14 @@ export const SamlAuth = () => {
|
|||||||
title: 'Settings stored',
|
title: 'Settings stored',
|
||||||
type: 'success',
|
type: 'success',
|
||||||
});
|
});
|
||||||
|
saveScimSettings();
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
setToastApiError(formatUnknownError(error));
|
setToastApiError(formatUnknownError(error));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const scimEnabled = useUiFlag('scimApi');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Grid container sx={{ mb: 3 }}>
|
<Grid container sx={{ mb: 3 }}>
|
||||||
@ -263,6 +286,31 @@ export const SamlAuth = () => {
|
|||||||
setValue={setValue}
|
setValue={setValue}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<ConditionallyRender
|
||||||
|
condition={scimEnabled}
|
||||||
|
show={
|
||||||
|
<ScimConfigSettings
|
||||||
|
disabled={!data.enabled}
|
||||||
|
settings={settings}
|
||||||
|
enabled={enabled}
|
||||||
|
setEnabled={setEnabled}
|
||||||
|
assumeControlOfExisting={assumeControlOfExisting}
|
||||||
|
setAssumeControlOfExisting={
|
||||||
|
setAssumeControlOfExisting
|
||||||
|
}
|
||||||
|
newToken={newToken}
|
||||||
|
tokenGenerationDialog={tokenGenerationDialog}
|
||||||
|
setTokenGenerationDialog={setTokenGenerationDialog}
|
||||||
|
tokenDialog={tokenDialog}
|
||||||
|
setTokenDialog={setTokenDialog}
|
||||||
|
loading={scimLoading}
|
||||||
|
onGenerateNewTokenConfirm={
|
||||||
|
onGenerateNewTokenConfirm
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
|
||||||
<AutoCreateForm
|
<AutoCreateForm
|
||||||
data={data}
|
data={data}
|
||||||
setValue={setValue}
|
setValue={setValue}
|
||||||
|
@ -1,67 +1,51 @@
|
|||||||
import type React from 'react';
|
|
||||||
import { useEffect, useState } from 'react';
|
|
||||||
import { Button, FormControlLabel, Grid, Switch } from '@mui/material';
|
import { Button, FormControlLabel, Grid, Switch } from '@mui/material';
|
||||||
import { Alert } from '@mui/material';
|
import { Alert } from '@mui/material';
|
||||||
import useToast from 'hooks/useToast';
|
|
||||||
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
|
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
|
||||||
import { useScimSettings } from 'hooks/api/getters/useScimSettings/useScimSettings';
|
|
||||||
import { useScimSettingsApi } from 'hooks/api/actions/useScimSettingsApi/useScimSettingsApi';
|
|
||||||
import { formatUnknownError } from 'utils/formatUnknownError';
|
|
||||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
|
||||||
import { ScimTokenGenerationDialog } from './ScimTokenGenerationDialog';
|
import { ScimTokenGenerationDialog } from './ScimTokenGenerationDialog';
|
||||||
import { ScimTokenDialog } from './ScimTokenDialog';
|
import { ScimTokenDialog } from './ScimTokenDialog';
|
||||||
|
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||||
|
import type { ScimSettings } from 'hooks/api/getters/useScimSettings/useScimSettings';
|
||||||
|
|
||||||
export const ScimSettings = () => {
|
export interface IScimSettingsParameters {
|
||||||
const { setToastData, setToastApiError } = useToast();
|
disabled: boolean;
|
||||||
|
loading: boolean;
|
||||||
|
enabled: boolean;
|
||||||
|
setEnabled: React.Dispatch<React.SetStateAction<boolean>>;
|
||||||
|
assumeControlOfExisting: boolean;
|
||||||
|
setAssumeControlOfExisting: React.Dispatch<React.SetStateAction<boolean>>;
|
||||||
|
newToken: string;
|
||||||
|
settings: ScimSettings;
|
||||||
|
tokenGenerationDialog: boolean;
|
||||||
|
setTokenGenerationDialog: React.Dispatch<React.SetStateAction<boolean>>;
|
||||||
|
onGenerateNewTokenConfirm: () => void;
|
||||||
|
tokenDialog: boolean;
|
||||||
|
setTokenDialog: React.Dispatch<React.SetStateAction<boolean>>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ScimConfigSettings = ({
|
||||||
|
disabled,
|
||||||
|
loading,
|
||||||
|
enabled,
|
||||||
|
setEnabled,
|
||||||
|
assumeControlOfExisting,
|
||||||
|
setAssumeControlOfExisting,
|
||||||
|
newToken,
|
||||||
|
settings,
|
||||||
|
tokenGenerationDialog,
|
||||||
|
setTokenGenerationDialog,
|
||||||
|
onGenerateNewTokenConfirm,
|
||||||
|
tokenDialog,
|
||||||
|
setTokenDialog,
|
||||||
|
}: IScimSettingsParameters) => {
|
||||||
const { uiConfig } = useUiConfig();
|
const { uiConfig } = useUiConfig();
|
||||||
const { settings, refetch } = useScimSettings();
|
|
||||||
const { saveSettings, generateNewToken, errors, loading } =
|
|
||||||
useScimSettingsApi();
|
|
||||||
|
|
||||||
const [enabled, setEnabled] = useState(false);
|
|
||||||
|
|
||||||
const [tokenGenerationDialog, setTokenGenerationDialog] = useState(false);
|
|
||||||
const [tokenDialog, setTokenDialog] = useState(false);
|
|
||||||
const [newToken, setNewToken] = useState('');
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setEnabled(settings.enabled ?? false);
|
|
||||||
}, [settings]);
|
|
||||||
|
|
||||||
const onSubmit = async (event: React.SyntheticEvent) => {
|
|
||||||
event.preventDefault();
|
|
||||||
|
|
||||||
try {
|
|
||||||
await saveSettings({ enabled });
|
|
||||||
if (enabled && !settings.hasToken) {
|
|
||||||
const token = await generateNewToken();
|
|
||||||
setNewToken(token);
|
|
||||||
setTokenDialog(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
setToastData({
|
|
||||||
title: 'Settings stored',
|
|
||||||
type: 'success',
|
|
||||||
});
|
|
||||||
refetch();
|
|
||||||
} catch (error: unknown) {
|
|
||||||
setToastApiError(formatUnknownError(error));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const onGenerateNewToken = async () => {
|
const onGenerateNewToken = async () => {
|
||||||
setTokenGenerationDialog(true);
|
setTokenGenerationDialog(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onGenerateNewTokenConfirm = async () => {
|
|
||||||
setTokenGenerationDialog(false);
|
|
||||||
const token = await generateNewToken();
|
|
||||||
setNewToken(token);
|
|
||||||
setTokenDialog(true);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
<h3>SCIM Provisioning</h3>
|
||||||
<Grid container sx={{ mb: 3 }}>
|
<Grid container sx={{ mb: 3 }}>
|
||||||
<Grid item md={12}>
|
<Grid item md={12}>
|
||||||
<Alert severity='info'>
|
<Alert severity='info'>
|
||||||
@ -79,56 +63,68 @@ export const ScimSettings = () => {
|
|||||||
</Alert>
|
</Alert>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
<form onSubmit={onSubmit}>
|
<Grid container spacing={3}>
|
||||||
<Grid container spacing={3}>
|
<Grid item md={5} mb={2}>
|
||||||
<Grid item md={5} mb={2}>
|
<strong>Enable</strong>
|
||||||
<strong>Enable</strong>
|
<p>Enable SCIM provisioning.</p>
|
||||||
<p>Enable SCIM provisioning.</p>
|
|
||||||
</Grid>
|
|
||||||
<Grid item md={6}>
|
|
||||||
<FormControlLabel
|
|
||||||
control={
|
|
||||||
<Switch
|
|
||||||
onChange={(_, enabled) =>
|
|
||||||
setEnabled(enabled)
|
|
||||||
}
|
|
||||||
value={enabled}
|
|
||||||
name='enabled'
|
|
||||||
checked={enabled}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
label={enabled ? 'Enabled' : 'Disabled'}
|
|
||||||
/>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
</Grid>
|
||||||
|
<Grid item md={6}>
|
||||||
|
<FormControlLabel
|
||||||
|
control={
|
||||||
|
<Switch
|
||||||
|
onChange={(_, enabled) => setEnabled(enabled)}
|
||||||
|
value={enabled}
|
||||||
|
name='enabled'
|
||||||
|
checked={enabled}
|
||||||
|
disabled={disabled}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
label={enabled ? 'Enabled' : 'Disabled'}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
<Grid container spacing={3}>
|
<Grid container spacing={3}>
|
||||||
<Grid item md={5}>
|
<Grid item md={5} mb={2}>
|
||||||
<Button
|
<strong>Assume control</strong>
|
||||||
variant='contained'
|
<p>Assumes control of users and groups</p>
|
||||||
color='primary'
|
|
||||||
type='submit'
|
|
||||||
disabled={loading}
|
|
||||||
>
|
|
||||||
Save
|
|
||||||
</Button>
|
|
||||||
<ConditionallyRender
|
|
||||||
condition={Boolean(settings.hasToken)}
|
|
||||||
show={
|
|
||||||
<Button
|
|
||||||
variant='outlined'
|
|
||||||
color='error'
|
|
||||||
disabled={loading}
|
|
||||||
onClick={onGenerateNewToken}
|
|
||||||
sx={{ ml: 1 }}
|
|
||||||
>
|
|
||||||
Generate new token
|
|
||||||
</Button>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</form>
|
<Grid item md={6}>
|
||||||
|
<FormControlLabel
|
||||||
|
control={
|
||||||
|
<Switch
|
||||||
|
onChange={(_, set_enabled) =>
|
||||||
|
setAssumeControlOfExisting(set_enabled)
|
||||||
|
}
|
||||||
|
value={assumeControlOfExisting}
|
||||||
|
name='assumeControlOfExisting'
|
||||||
|
checked={assumeControlOfExisting}
|
||||||
|
disabled={disabled}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
label={assumeControlOfExisting ? 'Enabled' : 'Disabled'}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<Grid container spacing={3}>
|
||||||
|
<Grid item md={5}>
|
||||||
|
<ConditionallyRender
|
||||||
|
condition={Boolean(settings.hasToken)}
|
||||||
|
show={
|
||||||
|
<Button
|
||||||
|
variant='outlined'
|
||||||
|
color='error'
|
||||||
|
disabled={loading}
|
||||||
|
onClick={onGenerateNewToken}
|
||||||
|
sx={{ ml: 1 }}
|
||||||
|
>
|
||||||
|
Generate new token
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
<ScimTokenGenerationDialog
|
<ScimTokenGenerationDialog
|
||||||
open={tokenGenerationDialog}
|
open={tokenGenerationDialog}
|
||||||
setOpen={setTokenGenerationDialog}
|
setOpen={setTokenGenerationDialog}
|
||||||
|
@ -10,11 +10,13 @@ const ENDPOINT = 'api/admin/scim-settings';
|
|||||||
export type ScimSettings = {
|
export type ScimSettings = {
|
||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
hasToken: boolean;
|
hasToken: boolean;
|
||||||
|
assumeControlOfExisting: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
const DEFAULT_DATA: ScimSettings = {
|
const DEFAULT_DATA: ScimSettings = {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
hasToken: false,
|
hasToken: false,
|
||||||
|
assumeControlOfExisting: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useScimSettings = () => {
|
export const useScimSettings = () => {
|
||||||
|
66
frontend/src/hooks/useScim.ts
Normal file
66
frontend/src/hooks/useScim.ts
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
import { useScimSettingsApi } from 'hooks/api/actions/useScimSettingsApi/useScimSettingsApi';
|
||||||
|
import { useEffect, useState } from 'react';
|
||||||
|
import { formatUnknownError } from 'utils/formatUnknownError';
|
||||||
|
import useToast from 'hooks/useToast';
|
||||||
|
import { useScimSettings } from './api/getters/useScimSettings/useScimSettings';
|
||||||
|
|
||||||
|
export const useScim = () => {
|
||||||
|
const [newToken, setNewToken] = useState('');
|
||||||
|
const [enabled, setEnabled] = useState(false);
|
||||||
|
const [tokenGenerationDialog, setTokenGenerationDialog] = useState(false);
|
||||||
|
const [tokenDialog, setTokenDialog] = useState(false);
|
||||||
|
const [assumeControlOfExisting, setAssumeControlOfExisting] =
|
||||||
|
useState(false);
|
||||||
|
|
||||||
|
const { saveSettings, generateNewToken, errors, loading } =
|
||||||
|
useScimSettingsApi();
|
||||||
|
|
||||||
|
const { settings, refetch } = useScimSettings();
|
||||||
|
const { setToastData, setToastApiError } = useToast();
|
||||||
|
const saveScimSettings = async () => {
|
||||||
|
try {
|
||||||
|
await saveSettings({ enabled, assumeControlOfExisting });
|
||||||
|
if (enabled && !settings.hasToken) {
|
||||||
|
const token = await generateNewToken();
|
||||||
|
setNewToken(token);
|
||||||
|
setTokenDialog(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
setToastData({
|
||||||
|
title: 'Settings stored',
|
||||||
|
type: 'success',
|
||||||
|
});
|
||||||
|
refetch();
|
||||||
|
} catch (error: unknown) {
|
||||||
|
setToastApiError(formatUnknownError(error));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const onGenerateNewTokenConfirm = async () => {
|
||||||
|
setTokenGenerationDialog(false);
|
||||||
|
const token = await generateNewToken();
|
||||||
|
setNewToken(token);
|
||||||
|
setTokenDialog(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setEnabled(settings.enabled ?? false);
|
||||||
|
setAssumeControlOfExisting(settings.assumeControlOfExisting ?? false);
|
||||||
|
}, [settings]);
|
||||||
|
|
||||||
|
return {
|
||||||
|
settings,
|
||||||
|
enabled,
|
||||||
|
setEnabled,
|
||||||
|
assumeControlOfExisting,
|
||||||
|
setAssumeControlOfExisting,
|
||||||
|
newToken,
|
||||||
|
tokenGenerationDialog,
|
||||||
|
setTokenGenerationDialog,
|
||||||
|
tokenDialog,
|
||||||
|
setTokenDialog,
|
||||||
|
loading,
|
||||||
|
saveScimSettings,
|
||||||
|
onGenerateNewTokenConfirm,
|
||||||
|
};
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user