mirror of https://github.com/boxyhq/jackson.git
Hide the connection info from the setup link UI (#2383)
* For dsync * For sso * Refactor EditConnection component to hide certain fields in setup view * Refactor EditConnection * Refactor directory-sync and sso-connection API handlers * Fix lint issue * wip * Fix updates * Fix authorization check and error message * Optimize * Sync lock files --------- Co-authored-by: Aswin V <vaswin91@gmail.com> Co-authored-by: Deepak Prabhakara <deepak@boxyhq.com>
This commit is contained in:
parent
7197ee59b2
commit
06c7d38b37
|
@ -174,6 +174,13 @@ const EditConnection = ({ connection, setupLinkToken, isSettingsView = false }:
|
|||
? '/admin/settings/sso-connection'
|
||||
: '/admin/sso-connection';
|
||||
|
||||
const fieldsToHideInSetupView = ['forceAuthn', 'clientID', 'clientSecret', 'idpCertExpiry', 'idpMetadata'];
|
||||
const readOnlyFields = filteredFieldsByConnection
|
||||
.filter((field) => field.attributes.editable === false)
|
||||
.filter(({ attributes: { hideInSetupView } }) => (setupLinkToken ? !hideInSetupView : true))
|
||||
.filter(excludeFallback(formObj))
|
||||
.filter((field) => (setupLinkToken ? !fieldsToHideInSetupView.includes(field.key) : true));
|
||||
|
||||
return (
|
||||
<>
|
||||
<LinkBack href={backUrl} />
|
||||
|
@ -187,20 +194,22 @@ const EditConnection = ({ connection, setupLinkToken, isSettingsView = false }:
|
|||
<form onSubmit={save}>
|
||||
<div className='min-w-[28rem] rounded border border-gray-200 bg-white p-6 dark:border-gray-700 dark:bg-gray-800 lg:border-none lg:p-0'>
|
||||
<div className='flex flex-col gap-0 lg:flex-row lg:gap-4'>
|
||||
<div className='w-full rounded border-gray-200 dark:border-gray-700 lg:w-3/5 lg:border lg:p-3'>
|
||||
<div
|
||||
className={`w-full rounded border-gray-200 dark:border-gray-700 lg:border lg:p-3 ${readOnlyFields.length > 0 ? 'lg:w-3/5' : ''}`}>
|
||||
{filteredFieldsByConnection
|
||||
.filter((field) => field.attributes.editable !== false)
|
||||
.filter(({ attributes: { hideInSetupView } }) => (setupLinkToken ? !hideInSetupView : true))
|
||||
.filter(excludeFallback(formObj))
|
||||
.filter((field) => (setupLinkToken ? !fieldsToHideInSetupView.includes(field.key) : true))
|
||||
.map(renderFieldList({ isEditView: true, formObj, setFormObj, activateFallback }))}
|
||||
</div>
|
||||
<div className='w-full rounded border-gray-200 dark:border-gray-700 lg:w-2/5 lg:border lg:p-3'>
|
||||
{filteredFieldsByConnection
|
||||
.filter((field) => field.attributes.editable === false)
|
||||
.filter(({ attributes: { hideInSetupView } }) => (setupLinkToken ? !hideInSetupView : true))
|
||||
.filter(excludeFallback(formObj))
|
||||
.map(renderFieldList({ isEditView: true, formObj, setFormObj, activateFallback }))}
|
||||
</div>
|
||||
{readOnlyFields.length > 0 && (
|
||||
<div className='w-full rounded border-gray-200 dark:border-gray-700 lg:w-2/5 lg:border lg:p-3'>
|
||||
{readOnlyFields.map(
|
||||
renderFieldList({ isEditView: true, formObj, setFormObj, activateFallback })
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className='flex w-full lg:mt-6'>
|
||||
<ButtonPrimary type='submit'>{t('save_changes')}</ButtonPrimary>
|
||||
|
|
|
@ -48,10 +48,13 @@ export const ToggleConnectionStatus: FC<Props> = (props) => {
|
|||
}
|
||||
);
|
||||
|
||||
const response: ApiResponse = await res.json();
|
||||
if (!res.ok) {
|
||||
const response: ApiResponse = await res.json();
|
||||
|
||||
if ('error' in response) {
|
||||
errorToast(response.error.message);
|
||||
}
|
||||
|
||||
if ('error' in response) {
|
||||
errorToast(response.error.message);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,10 +6,7 @@ import { DirectoryTab } from '../dsync';
|
|||
import type { Directory } from '../types';
|
||||
import { Loading, Error, PageHeader, Badge, Alert, InputWithCopyButton, LinkPrimary } from '../shared';
|
||||
|
||||
type ExcludeFields = keyof Pick<Directory, 'tenant' | 'product' | 'webhook'>;
|
||||
|
||||
// TODO:
|
||||
// Add the toast after copying the google auth url
|
||||
type ExcludeFields = keyof Pick<Directory, 'id' | 'tenant' | 'product' | 'webhook'>;
|
||||
|
||||
export const DirectoryInfo = ({
|
||||
urls,
|
||||
|
@ -37,7 +34,9 @@ export const DirectoryInfo = ({
|
|||
return null;
|
||||
}
|
||||
|
||||
const authorizedGoogle = directory.google_access_token && directory.google_refresh_token;
|
||||
const authorizedGoogle =
|
||||
directory?.google_authorized || (directory?.google_access_token && directory?.google_refresh_token);
|
||||
const hideInfo = excludeFields.length === 4 && directory.type != 'google';
|
||||
|
||||
return (
|
||||
<>
|
||||
|
@ -60,62 +59,66 @@ export const DirectoryInfo = ({
|
|||
</Alert>
|
||||
</div>
|
||||
)}
|
||||
<div className={`rounded border ${hideTabs ? 'mt-5' : ''}`}>
|
||||
<dl className='divide-y'>
|
||||
<div className='px-4 py-4 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6'>
|
||||
<dt className='text-sm font-medium text-gray-500'>{t('bui-dsync-directory-id')}</dt>
|
||||
<dd className='mt-1 text-sm text-gray-900 sm:col-span-2 sm:mt-0'>{directory.id}</dd>
|
||||
</div>
|
||||
{!excludeFields.includes('tenant') && (
|
||||
<div className='px-4 py-4 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6'>
|
||||
<dt className='text-sm font-medium text-gray-500'>{t('bui-dsync-tenant')}</dt>
|
||||
<dd className='mt-1 text-sm text-gray-900 sm:col-span-2 sm:mt-0'>{directory.tenant}</dd>
|
||||
</div>
|
||||
)}
|
||||
{!excludeFields.includes('product') && (
|
||||
<div className='px-4 py-4 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6'>
|
||||
<dt className='text-sm font-medium text-gray-500'>{t('bui-dsync-product')}</dt>
|
||||
<dd className='mt-1 text-sm text-gray-900 sm:col-span-2 sm:mt-0'>{directory.product}</dd>
|
||||
</div>
|
||||
)}
|
||||
{!excludeFields.includes('webhook') && (
|
||||
<>
|
||||
{!hideInfo && (
|
||||
<div className={`rounded border ${hideTabs ? 'mt-5' : ''}`}>
|
||||
<dl className='divide-y'>
|
||||
{!excludeFields.includes('id') && (
|
||||
<div className='px-4 py-4 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6'>
|
||||
<dt className='text-sm font-medium text-gray-500'>{t('bui-dsync-webhook-endpoint')}</dt>
|
||||
<dd className='mt-1 text-sm text-gray-900 sm:col-span-2 sm:mt-0'>
|
||||
{directory.webhook.endpoint || '-'}
|
||||
</dd>
|
||||
<dt className='text-sm font-medium text-gray-500'>{t('bui-dsync-directory-id')}</dt>
|
||||
<dd className='mt-1 text-sm text-gray-900 sm:col-span-2 sm:mt-0'>{directory.id}</dd>
|
||||
</div>
|
||||
)}
|
||||
{!excludeFields.includes('tenant') && (
|
||||
<div className='px-4 py-4 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6'>
|
||||
<dt className='text-sm font-medium text-gray-500'>{t('bui-dsync-webhook-secret')}</dt>
|
||||
<dd className='mt-1 text-sm text-gray-900 sm:col-span-2 sm:mt-0'>
|
||||
{directory.webhook.secret || '-'}
|
||||
</dd>
|
||||
<dt className='text-sm font-medium text-gray-500'>{t('bui-dsync-tenant')}</dt>
|
||||
<dd className='mt-1 text-sm text-gray-900 sm:col-span-2 sm:mt-0'>{directory.tenant}</dd>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
{directory.type === 'google' && (
|
||||
<>
|
||||
)}
|
||||
{!excludeFields.includes('product') && (
|
||||
<div className='px-4 py-4 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6'>
|
||||
<dt className='text-sm font-medium text-gray-500'>{t('bui-dsync-authorized-status')}</dt>
|
||||
<dd className='mt-1 text-sm text-gray-900 sm:col-span-2 sm:mt-0'>
|
||||
{authorizedGoogle ? (
|
||||
<Badge color='success'>{t('bui-dsync-authorized')}</Badge>
|
||||
) : (
|
||||
<Badge color='warning'>{t('bui-dsync-not-authorized')}</Badge>
|
||||
)}
|
||||
</dd>
|
||||
<dt className='text-sm font-medium text-gray-500'>{t('bui-dsync-product')}</dt>
|
||||
<dd className='mt-1 text-sm text-gray-900 sm:col-span-2 sm:mt-0'>{directory.product}</dd>
|
||||
</div>
|
||||
<div className='px-4 py-4 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6'>
|
||||
<dt className='text-sm font-medium text-gray-500'>{t('bui-dsync-google-domain')}</dt>
|
||||
<dd className='mt-1 text-sm text-gray-900 sm:col-span-2 sm:mt-0'>
|
||||
{directory.google_domain || '-'}
|
||||
</dd>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</dl>
|
||||
</div>
|
||||
)}
|
||||
{!excludeFields.includes('webhook') && (
|
||||
<>
|
||||
<div className='px-4 py-4 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6'>
|
||||
<dt className='text-sm font-medium text-gray-500'>{t('bui-dsync-webhook-endpoint')}</dt>
|
||||
<dd className='mt-1 text-sm text-gray-900 sm:col-span-2 sm:mt-0'>
|
||||
{directory.webhook.endpoint || '-'}
|
||||
</dd>
|
||||
</div>
|
||||
<div className='px-4 py-4 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6'>
|
||||
<dt className='text-sm font-medium text-gray-500'>{t('bui-dsync-webhook-secret')}</dt>
|
||||
<dd className='mt-1 text-sm text-gray-900 sm:col-span-2 sm:mt-0'>
|
||||
{directory.webhook.secret || '-'}
|
||||
</dd>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
{directory.type === 'google' && (
|
||||
<>
|
||||
<div className='px-4 py-4 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6'>
|
||||
<dt className='text-sm font-medium text-gray-500'>{t('bui-dsync-authorized-status')}</dt>
|
||||
<dd className='mt-1 text-sm text-gray-900 sm:col-span-2 sm:mt-0'>
|
||||
{authorizedGoogle ? (
|
||||
<Badge color='success'>{t('bui-dsync-authorized')}</Badge>
|
||||
) : (
|
||||
<Badge color='warning'>{t('bui-dsync-not-authorized')}</Badge>
|
||||
)}
|
||||
</dd>
|
||||
</div>
|
||||
<div className='px-4 py-4 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6'>
|
||||
<dt className='text-sm font-medium text-gray-500'>{t('bui-dsync-google-domain')}</dt>
|
||||
<dd className='mt-1 text-sm text-gray-900 sm:col-span-2 sm:mt-0'>
|
||||
{directory.google_domain || '-'}
|
||||
</dd>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</dl>
|
||||
</div>
|
||||
)}
|
||||
{directory.scim.endpoint && directory.scim.secret && (
|
||||
<div className='mt-4 space-y-4 rounded border p-6'>
|
||||
<div className='form-control'>
|
||||
|
|
|
@ -6,7 +6,7 @@ export const useDirectory = (getDirectoryUrl: string) => {
|
|||
const { data, error, isLoading } = useSWR(getDirectoryUrl, fetcher);
|
||||
|
||||
return {
|
||||
directory: data?.data as Directory,
|
||||
directory: data?.data as Directory & { google_authorized?: boolean },
|
||||
isLoadingDirectory: isLoading,
|
||||
directoryError: error,
|
||||
};
|
||||
|
|
|
@ -38,11 +38,11 @@ const handlePATCH = async (req: NextApiRequest, res: NextApiResponse) => {
|
|||
const { data, error } = await directorySyncController.directories.update(directoryId, { deactivated });
|
||||
|
||||
if (data) {
|
||||
return res.status(200).json({ data });
|
||||
res.json({ data: null });
|
||||
}
|
||||
|
||||
if (error) {
|
||||
return res.status(error.code).json({ error });
|
||||
res.status(error.code).json({ error });
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -55,11 +55,21 @@ const handleGET = async (req: NextApiRequest, res: NextApiResponse) => {
|
|||
const { data, error } = await directorySyncController.directories.get(directoryId);
|
||||
|
||||
if (data) {
|
||||
return res.json({ data });
|
||||
res.json({
|
||||
data: {
|
||||
id: data.id,
|
||||
type: data.type,
|
||||
name: data.name,
|
||||
deactivated: data.deactivated,
|
||||
scim: data.scim,
|
||||
google_domain: data.google_domain,
|
||||
google_authorized: data.google_access_token && data.google_refresh_token, // Indicate if the Google authorization is complete
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (error) {
|
||||
return res.status(error.code).json({ error });
|
||||
res.status(error.code).json({ error });
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -72,10 +82,10 @@ const handleDELETE = async (req: NextApiRequest, res: NextApiResponse) => {
|
|||
const { error } = await directorySyncController.directories.delete(directoryId);
|
||||
|
||||
if (error) {
|
||||
return res.status(error.code).json({ error });
|
||||
res.status(error.code).json({ error });
|
||||
}
|
||||
|
||||
return res.json({ data: null });
|
||||
res.json({ data: null });
|
||||
};
|
||||
|
||||
export default handler;
|
||||
|
|
|
@ -46,11 +46,15 @@ const handlePOST = async (req: NextApiRequest, res: NextApiResponse, setupLink:
|
|||
const { data, error } = await directorySyncController.directories.create(directory);
|
||||
|
||||
if (data) {
|
||||
return res.status(201).json({ data });
|
||||
res.status(201).json({
|
||||
data: {
|
||||
id: data.id,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (error) {
|
||||
return res.status(error.code).json({ error });
|
||||
res.status(error.code).json({ error });
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -58,35 +62,26 @@ const handlePOST = async (req: NextApiRequest, res: NextApiResponse, setupLink:
|
|||
const handleGET = async (req: NextApiRequest, res: NextApiResponse, setupLink: SetupLink) => {
|
||||
const { directorySyncController } = await jackson();
|
||||
|
||||
const { offset, limit, pageToken } = req.query as { offset: string; limit: string; pageToken?: string };
|
||||
|
||||
const pageOffset = parseInt(offset);
|
||||
const pageLimit = parseInt(limit);
|
||||
|
||||
const {
|
||||
data,
|
||||
error,
|
||||
pageToken: nextPageToken,
|
||||
} = await directorySyncController.directories.getAll({
|
||||
pageOffset,
|
||||
pageLimit,
|
||||
pageToken,
|
||||
});
|
||||
|
||||
if (nextPageToken) {
|
||||
res.setHeader('jackson-pagetoken', nextPageToken);
|
||||
}
|
||||
const { data, error } = await directorySyncController.directories.getByTenantAndProduct(
|
||||
setupLink.tenant,
|
||||
setupLink.product
|
||||
);
|
||||
|
||||
if (data) {
|
||||
const filteredData = data.filter(
|
||||
(directory) => directory.tenant === setupLink.tenant && directory.product === setupLink.product
|
||||
);
|
||||
const directories = data.map((directory) => {
|
||||
return {
|
||||
id: directory.id,
|
||||
type: directory.type,
|
||||
name: directory.name,
|
||||
deactivated: directory.deactivated,
|
||||
};
|
||||
});
|
||||
|
||||
return res.status(200).json({ data: filteredData });
|
||||
res.json({ data: directories });
|
||||
}
|
||||
|
||||
if (error) {
|
||||
return res.status(error.code).json({ error });
|
||||
res.status(error.code).json({ error });
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import type { NextApiRequest, NextApiResponse } from 'next';
|
||||
import jackson from '@lib/jackson';
|
||||
import type { SetupLink } from '@boxyhq/saml-jackson';
|
||||
|
||||
const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
const { setupLinkController } = await jackson();
|
||||
|
@ -9,11 +8,11 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
|||
const { token } = req.query as { token: string };
|
||||
|
||||
try {
|
||||
const setupLink = await setupLinkController.getByToken(token);
|
||||
await setupLinkController.getByToken(token);
|
||||
|
||||
switch (method) {
|
||||
case 'GET':
|
||||
return await handleGET(req, res, setupLink);
|
||||
return await handleGET(req, res);
|
||||
default:
|
||||
res.setHeader('Allow', 'GET');
|
||||
res.status(405).json({ error: { message: `Method ${method} Not Allowed` } });
|
||||
|
@ -25,17 +24,30 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
|||
}
|
||||
};
|
||||
|
||||
const handleGET = async (req: NextApiRequest, res: NextApiResponse, setupLink: SetupLink) => {
|
||||
const handleGET = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
const { connectionAPIController } = await jackson();
|
||||
|
||||
const { id } = req.query as { id: string };
|
||||
|
||||
const connections = await connectionAPIController.getConnections({
|
||||
tenant: setupLink.tenant,
|
||||
product: setupLink.product,
|
||||
clientID: id,
|
||||
});
|
||||
|
||||
return res.json({ data: connections.filter((l) => l.clientID === id)[0] });
|
||||
if (!connections || connections.length === 0) {
|
||||
res.status(404).json({ error: { message: 'Connection not found.' } });
|
||||
}
|
||||
|
||||
const connection = connections[0];
|
||||
|
||||
res.json({
|
||||
data: {
|
||||
clientID: connection.clientID,
|
||||
clientSecret: connection.clientSecret,
|
||||
deactivated: connection.deactivated,
|
||||
...('idpMetadata' in connection ? { idpMetadata: {}, metadataUrl: connection.metadataUrl } : undefined),
|
||||
...('oidcProvider' in connection ? { oidcProvider: connection.oidcProvider } : undefined),
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
export default handler;
|
||||
|
|
|
@ -18,9 +18,9 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
|||
case 'POST':
|
||||
return await handlePOST(req, res, setupLink);
|
||||
case 'PATCH':
|
||||
return await handlePATCH(req, res, setupLink);
|
||||
return await handlePATCH(req, res);
|
||||
case 'DELETE':
|
||||
return await handleDELETE(req, res, setupLink);
|
||||
return await handleDELETE(req, res);
|
||||
default:
|
||||
res.setHeader('Allow', 'GET, POST, PATCH, DELETE');
|
||||
res.status(405).json({ error: { message: `Method ${method} Not Allowed` } });
|
||||
|
@ -40,7 +40,31 @@ const handleGET = async (req: NextApiRequest, res: NextApiResponse, setupLink: S
|
|||
product: setupLink.product,
|
||||
});
|
||||
|
||||
return res.json(connections);
|
||||
const _connections = connections.map((connection) => {
|
||||
return {
|
||||
clientID: connection.clientID,
|
||||
name: connection.name,
|
||||
deactivated: connection.deactivated,
|
||||
...('idpMetadata' in connection
|
||||
? {
|
||||
idpMetadata: {
|
||||
provider: connection.idpMetadata.provider,
|
||||
friendlyProviderName: connection.idpMetadata.friendlyProviderName,
|
||||
},
|
||||
}
|
||||
: undefined),
|
||||
...('oidcProvider' in connection
|
||||
? {
|
||||
oidcProvider: {
|
||||
provider: connection.oidcProvider.provider,
|
||||
friendlyProviderName: connection.oidcProvider.friendlyProviderName,
|
||||
},
|
||||
}
|
||||
: undefined),
|
||||
};
|
||||
});
|
||||
|
||||
res.json(_connections);
|
||||
};
|
||||
|
||||
const handlePOST = async (req: NextApiRequest, res: NextApiResponse, setupLink: SetupLink) => {
|
||||
|
@ -54,47 +78,75 @@ const handlePOST = async (req: NextApiRequest, res: NextApiResponse, setupLink:
|
|||
const { isSAML, isOIDC } = strategyChecker(req);
|
||||
|
||||
if (isSAML) {
|
||||
return res.status(201).json({ data: await connectionAPIController.createSAMLConnection(body) });
|
||||
await connectionAPIController.createSAMLConnection(body);
|
||||
} else if (isOIDC) {
|
||||
return res
|
||||
.status(201)
|
||||
.json({ data: await connectionAPIController.createOIDCConnection(oidcMetadataParse(body)) });
|
||||
await connectionAPIController.createOIDCConnection(oidcMetadataParse(body));
|
||||
} else {
|
||||
throw { message: 'Missing SSO connection params', statusCode: 400 };
|
||||
}
|
||||
|
||||
res.status(201).json({ data: null });
|
||||
};
|
||||
|
||||
const handleDELETE = async (req: NextApiRequest, res: NextApiResponse, setupLink: SetupLink) => {
|
||||
const handleDELETE = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
const { connectionAPIController } = await jackson();
|
||||
|
||||
const body = {
|
||||
...req.query,
|
||||
tenant: setupLink.tenant,
|
||||
product: setupLink.product,
|
||||
};
|
||||
const { clientID, clientSecret } = req.query as { clientID: string; clientSecret: string };
|
||||
|
||||
await connectionAPIController.deleteConnections(body);
|
||||
await connectionAPIController.deleteConnections({ clientID, clientSecret });
|
||||
|
||||
return res.json({ data: null });
|
||||
res.json({ data: null });
|
||||
};
|
||||
|
||||
const handlePATCH = async (req: NextApiRequest, res: NextApiResponse, setupLink: SetupLink) => {
|
||||
const handlePATCH = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
const { connectionAPIController } = await jackson();
|
||||
|
||||
const body = {
|
||||
...req.body,
|
||||
...setupLink,
|
||||
};
|
||||
const {
|
||||
deactivated,
|
||||
clientID,
|
||||
metadataUrl,
|
||||
encodedRawMetadata,
|
||||
oidcClientId,
|
||||
oidcClientSecret,
|
||||
oidcDiscoveryUrl,
|
||||
} = req.body;
|
||||
|
||||
const connections = await connectionAPIController.getConnections({
|
||||
clientID,
|
||||
});
|
||||
|
||||
if (!connections || connections.length === 0) {
|
||||
throw { message: 'Connection not found', statusCode: 404 };
|
||||
}
|
||||
|
||||
const { isSAML, isOIDC } = strategyChecker(req);
|
||||
const { tenant, product, clientSecret } = connections[0];
|
||||
|
||||
const body = {
|
||||
tenant,
|
||||
product,
|
||||
clientID,
|
||||
clientSecret,
|
||||
...('deactivated' in req.body ? { deactivated } : undefined),
|
||||
...(isSAML ? { metadataUrl, encodedRawMetadata } : undefined),
|
||||
...(isOIDC
|
||||
? {
|
||||
oidcClientId,
|
||||
oidcClientSecret,
|
||||
oidcDiscoveryUrl,
|
||||
}
|
||||
: undefined),
|
||||
};
|
||||
|
||||
if (isSAML) {
|
||||
res.json({ data: await connectionAPIController.updateSAMLConnection(body) });
|
||||
await connectionAPIController.updateSAMLConnection(body as any);
|
||||
} else if (isOIDC) {
|
||||
res.json({ data: await connectionAPIController.updateOIDCConnection(oidcMetadataParse(body) as any) });
|
||||
await connectionAPIController.updateOIDCConnection(oidcMetadataParse(body as any));
|
||||
} else {
|
||||
throw { message: 'Missing SSO connection params', statusCode: 400 };
|
||||
}
|
||||
|
||||
res.status(204).end();
|
||||
};
|
||||
|
||||
export default handler;
|
||||
|
|
|
@ -24,6 +24,7 @@ const DirectoryDetailsPage: NextPage = () => {
|
|||
}}
|
||||
hideTabs={true}
|
||||
displayGoogleAuthButton={true}
|
||||
excludeFields={['id', 'tenant', 'product', 'webhook']}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
Loading…
Reference in New Issue