Tweaking SAML federation metadata url (#749)

* updated deps

* - validate tenant, product during setup link creation
- tweaked copy to clipboard icon
- tweaked error toast

* fixed toast durations

* moved idp configuration page and idp metadata url to .well-known path
This commit is contained in:
Deepak Prabhakara 2022-12-18 21:13:12 +00:00 committed by GitHub
parent 881a537a2a
commit 9611cf4a71
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 1338 additions and 6649 deletions

View File

@ -1,11 +1,6 @@
import { FormEvent, useState } from 'react';
import Link from 'next/link';
import {
CheckCircleIcon,
ExclamationCircleIcon,
ClipboardDocumentListIcon,
ArrowLeftIcon,
} from '@heroicons/react/24/outline';
import { ClipboardDocumentIcon, ArrowLeftIcon } from '@heroicons/react/24/outline';
import ConfirmationModal from '@components/ConfirmationModal';
import { useRouter } from 'next/router';
import { useTranslation } from 'next-i18next';
@ -31,13 +26,14 @@ const CreateSetupLink = (props: { service: 'sso' | 'dsync' }) => {
}),
});
if (res.ok) {
setLoading(false);
const json = await res.json();
setUrl(json.data.url);
successToast(t('link_generated'));
} else {
errorToast(t('server_error'));
const rsp = await res.json();
errorToast(rsp?.error?.message || t('server_error'));
}
setLoading(false);
};
const regenerateLink = async (event) => {
event.preventDefault();
@ -90,7 +86,7 @@ const CreateSetupLink = (props: { service: 'sso' | 'dsync' }) => {
<span>Back</span>
</Link>
<div className='mt-5 min-w-[28rem] rounded border border-gray-200 bg-white p-6 dark:border-gray-700 dark:bg-gray-800'>
<h2 className='mb-5 mt-5 font-bold text-gray-700 dark:text-white md:text-xl'>
<h2 className='mb-5 font-bold text-gray-700 dark:text-white md:text-xl'>
{t('create_setup_link', {
service: props.service === 'sso' ? t('enterprise_sso') : t('directory_sync'),
})}
@ -135,50 +131,31 @@ const CreateSetupLink = (props: { service: 'sso' | 'dsync' }) => {
</div>
<div className='flex'>
<button
className={`btn-primary btn mx-2 mt-5 ${loading ? 'loading' : ''}`}
className={`btn-primary btn ${loading ? 'loading' : ''}`}
disabled={!formObj.tenant || !formObj.product || !formObj.type}
onClick={createLink}>
{'Generate'}
{t('generate')}
</button>
</div>
<p
role='status'
className={`mt-4 ml-2 inline-flex items-center ${
status === 'SUCCESS' || status === 'ERROR' ? 'opacity-100' : 'opacity-0'
} transition-opacity motion-reduce:transition-none`}>
{status === 'SUCCESS' && (
<span className='inline-flex items-center text-primary'>
<CheckCircleIcon aria-hidden className='mr-1 h-5 w-5'></CheckCircleIcon>
Link Generated
</span>
)}
{/* TODO: also display error message once we standardise the response format */}
{status === 'ERROR' && (
<span className='inline-flex items-center text-red-900'>
<ExclamationCircleIcon aria-hidden className='mr-1 h-5 w-5'></ExclamationCircleIcon>
ERROR
</span>
)}
</p>
<ConfirmationModal
title='Delete the setup link'
description='This action cannot be undone. This will permanently delete the link.'
visible={delModalVisible}
onConfirm={regenerateLink}
onCancel={toggleDelConfirm}
actionButtonText={'Regenerate'}
actionButtonText={t('regenerate')}
/>
</div>
{url && (
<div className='mt-5 min-w-[28rem] rounded border border-gray-200 bg-white p-6 dark:border-gray-700 dark:bg-gray-800'>
<h2 className='mb-5 mt-5 font-bold text-gray-700 dark:text-white md:text-xl'>
<h2 className='mb-5 font-bold text-gray-700 dark:text-white md:text-xl'>
{url
? t('setup_link_info')
: t('create_setup_link', {
service: props.service === 'sso' ? t('enterprise_sso') : t('directory_sync'),
})}
</h2>
<div className='form-control p-2'>
<div className='form-control'>
<div className='input-group'>
<button
className='btn-primary btn h-10 p-2 text-white'
@ -186,14 +163,14 @@ const CreateSetupLink = (props: { service: 'sso' | 'dsync' }) => {
copyToClipboard(url);
successToast(t('copied'));
}}>
<ClipboardDocumentListIcon className='h-6 w-6' />
<ClipboardDocumentIcon className='h-6 w-6' />
</button>
<input type='text' readOnly value={url} className='input-bordered input h-10 w-full' />
</div>
</div>
<div className='flex'>
<button
className={`btn-primary btn mx-2 mt-5 ${loading1 ? 'loading' : ''}`}
className={`btn-primary btn mt-5 ${loading1 ? 'loading' : ''}`}
disabled={!formObj.tenant || !formObj.product || !formObj.type}
onClick={
url
@ -202,7 +179,7 @@ const CreateSetupLink = (props: { service: 'sso' | 'dsync' }) => {
}
: createLink
}>
{url ? 'Regenerate Link' : 'Generate'}
{url ? t('regenerate') : t('generate')}
</button>
</div>
</div>

View File

@ -46,12 +46,13 @@ const SuccessToast = ({ message }: { message: string }) => {
export const errorToast = (message: string) => {
toast.custom(() => <ErrorToast message={message} />, {
id: 'custom-error-toast',
duration: Infinity,
});
};
export const successToast = (message: string) => {
toast.custom(() => <SuccessToast message={message} />, {
id: 'custom-success-toast',
duration: 5000,
duration: 10000,
});
};

View File

@ -1,7 +1,7 @@
import Link from 'next/link';
import { useRouter } from 'next/router';
import { useState } from 'react';
import { ArrowLeftIcon, ClipboardDocumentListIcon } from '@heroicons/react/24/outline';
import { ArrowLeftIcon, ClipboardDocumentIcon } from '@heroicons/react/24/outline';
import { getCommonFields } from './fieldCatalog';
import { saveConnection, fieldCatalogFilterByConnection, renderFieldList } from './utils';
import { mutate } from 'swr';
@ -74,7 +74,7 @@ const Add = ({ setupToken, idpEntityID }: AddProps) => {
copyToClipboard(idpEntityID);
successToast(t('copied'));
}}>
<ClipboardDocumentListIcon className='h-6 w-6' />
<ClipboardDocumentIcon className='h-6 w-6' />
</button>
<input type='text' readOnly value={idpEntityID} className='input-bordered input h-10 w-4/5' />
</div>

View File

@ -2,7 +2,7 @@ import Link from 'next/link';
import {
ArrowLeftIcon,
ArrowRightIcon,
ClipboardDocumentListIcon,
ClipboardDocumentIcon,
LinkIcon,
PencilIcon,
PlusIcon,
@ -80,7 +80,7 @@ const Connections = ({
copyToClipboard(idpEntityID);
successToast(t('copied'));
}}>
<ClipboardDocumentListIcon className='h-6 w-6' />
<ClipboardDocumentIcon className='h-6 w-6' />
</button>
<input type='text' readOnly value={idpEntityID} className='input-bordered input h-10 w-4/5' />
</div>

View File

@ -26,6 +26,18 @@ const links = [
'Our OpenID configuration URI which your customers will need if they are connecting via OAuth 2.0 or Open ID Connect.',
href: '/.well-known/openid-configuration',
},
{
title: 'IdP Metadata',
description:
'The metadata file that your customers who use our SAML federation feature will need to set up SAML SP configuration on their application.',
href: '/.well-known/idp-metadata',
},
{
title: 'IdP Configuration',
description:
'The configuration setup guide that your customers who use our SAML federation feature will need to set up SAML SP configuration on their application.',
href: '/.well-known/idp-configuration',
},
];
const WellKnownURLs = ({ className }: { className?: string }) => {

View File

@ -2,7 +2,7 @@ import Link from 'next/link';
import {
ArrowLeftIcon,
ArrowRightIcon,
ClipboardDocumentListIcon,
ClipboardDocumentIcon,
PlusIcon,
ArrowPathIcon,
TrashIcon,
@ -114,7 +114,7 @@ const LinkList = ({ service }) => {
<td className='px-6 py-3'>
<span className='inline-flex items-baseline'>
<div className='tooltip' data-tip={t('copy')}>
<ClipboardDocumentListIcon
<ClipboardDocumentIcon
className='mr-3 h-5 w-5 cursor-pointer text-secondary hover:text-green-200'
onClick={() => {
copyToClipboard(link.url);
@ -187,7 +187,7 @@ const LinkList = ({ service }) => {
description='This action cannot be undone. This will permanently delete the old setup link.'
visible={showRegenConfirmModal}
onConfirm={invokeRegenerate}
actionButtonText={'Regenerate'}
actionButtonText={t('regenerate')}
onCancel={toggleRegenConfirmModal}></ConfirmationModal>
<ConfirmationModal
title='Delete this setup link?'

View File

@ -36,7 +36,7 @@ const handleGET = async (req: NextApiRequest, res: NextApiResponse) => {
try {
const app = await samlFederatedController.app.get(id);
const metadata = await samlFederatedController.app.getMetadata(id);
const metadata = await samlFederatedController.app.getMetadata();
return res.status(200).json({
data: {

View File

@ -7,14 +7,6 @@ import { promisify } from 'util';
const pipeline = promisify(stream.pipeline);
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
const { checkLicense } = await jackson();
if (!(await checkLicense())) {
return res.status(404).json({
error: { message: 'License not found. Please add a valid license to use this feature.' },
});
}
const { method } = req;
switch (method) {
@ -30,15 +22,15 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
const handleGET = async (req: NextApiRequest, res: NextApiResponse) => {
const { samlFederatedController } = await jackson();
const { appId, download } = req.query as { appId: string; download: any };
const { download } = req.query as { download: any };
try {
const metadata = await samlFederatedController.app.getMetadata(appId);
const metadata = await samlFederatedController.app.getMetadata();
res.setHeader('Content-type', 'text/xml');
if (download || download === '') {
res.setHeader('Content-Disposition', `attachment; filename=saml-metadata-${appId}.xml`);
res.setHeader('Content-Disposition', `attachment; filename=saml-metadata.xml`);
await pipeline(metadata.xml, res);
return;

View File

@ -80,7 +80,8 @@ const AppsList: NextPage = () => {
<td className='px-6'>{app.product}</td>
<td className='px-6'>
<Link
href={`/admin/federated-saml/${app.id}/metadata`}
href={`/.well-known/idp-configuration`}
target='_blank'
className='link-secondary link underline-offset-4'>
{t('view')}
</Link>

View File

@ -1,115 +1,91 @@
import useSWR from 'swr';
import Link from 'next/link';
import type { NextPage } from 'next';
import { useRouter } from 'next/router';
import { useTranslation } from 'next-i18next';
import type { SAMLFederationAppWithMetadata } from '@boxyhq/saml-jackson';
import type { NextPage, InferGetStaticPropsType } from 'next';
import { fetcher } from '@lib/ui/utils';
import Loading from '@components/Loading';
import { errorToast } from '@components/Toast';
import type { ApiError, ApiSuccess } from 'types';
import LicenseRequired from '@components/LicenseRequired';
const Metadata: NextPage = () => {
const Metadata: NextPage<any> = ({ metadata }) => {
const { t } = useTranslation('common');
const router = useRouter();
const { id } = router.query as { id: string };
const { data, error } = useSWR<ApiSuccess<SAMLFederationAppWithMetadata>, ApiError>(
`/api/admin/federated-saml/${id}`,
fetcher
);
if (error) {
errorToast(error.message);
return null;
}
if (!data) {
return <Loading />;
}
const app = data.data;
return (
<LicenseRequired>
<h2 className='mb-5 mt-5 font-bold text-gray-700 md:text-xl'>{t('saml_federation_app_info')}</h2>
<div className='rounded border border-gray-200 bg-white p-6 dark:border-gray-700 dark:bg-gray-800'>
<div className='flex flex-col'>
<div className='space-y-3'>
<p className='text-sm leading-6 text-gray-800'>{t('saml_federation_app_info_details')}</p>
<div className='flex flex-row gap-5'>
<Link
href={`/api/federated-saml/${id}/metadata?download=true`}
className='btn-outline btn-secondary btn'>
<svg
className='mr-1 inline-block h-6 w-6'
fill='none'
viewBox='0 0 24 24'
stroke='currentColor'
aria-hidden
strokeWidth='2'>
<path
strokeLinecap='round'
strokeLinejoin='round'
d='M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4'
/>
</svg>
{t('download_metadata')}
</Link>
<Link
href={`/api/federated-saml/${id}/metadata`}
className='btn-outline btn-secondary btn'
target='_blank'>
{t('metadata_url')}
</Link>
<div className='my-10 mx-5 flex h-screen justify-center'>
<div className='rounded border border-gray-200 bg-white p-6 dark:border-gray-700 dark:bg-gray-800'>
<h2 className='mb-5 mt-5 font-bold text-gray-700 md:text-xl'>{t('saml_federation_app_info')}</h2>
<div className='flex flex-col'>
<div className='space-y-3'>
<p className='text-sm leading-6 text-gray-800'>{t('saml_federation_app_info_details')}</p>
<div className='flex flex-row gap-5'>
<Link
href={`/.well-known/idp-metadata?download=true`}
className='btn-outline btn-secondary btn'>
<svg
className='mr-1 inline-block h-6 w-6'
fill='none'
viewBox='0 0 24 24'
stroke='currentColor'
aria-hidden
strokeWidth='2'>
<path
strokeLinecap='round'
strokeLinejoin='round'
d='M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4'
/>
</svg>
{t('download_metadata')}
</Link>
<Link
href={`/.well-known/idp-metadata`}
className='btn-outline btn-secondary btn'
target='_blank'>
{t('metadata_url')}
</Link>
</div>
</div>
</div>
<div className='divider'>OR</div>
<div className='space-y-6'>
<div className='form-control w-full'>
<label className='label'>
<span className='label-text font-bold'>{t('sso_url')}</span>
</label>
<input
type='text'
className='input-bordered input w-full'
defaultValue={app.metadata.ssoUrl}
readOnly
/>
</div>
<div className='form-control w-full'>
<label className='label'>
<span className='label-text font-bold'>{t('entity_id')}</span>
</label>
<input
type='text'
className='input-bordered input w-full'
defaultValue={app.metadata.entityId}
readOnly
/>
</div>
<div className='form-control w-full'>
<label className='label'>
<div className='flex w-full items-center justify-between'>
<span className='label-text font-bold'>{t('x509_certificate')}</span>
<span>
<a
href='/.well-known/saml.cer'
target='_blank'
className='label-text font-bold text-gray-500'>
{t('download')}
</a>
</span>
</div>
</label>
<textarea
className='textarea-bordered textarea w-full'
rows={10}
defaultValue={app.metadata.x509cert.trim()}
readOnly></textarea>
<div className='divider'>OR</div>
<div className='space-y-6'>
<div className='form-control w-full'>
<label className='label'>
<span className='label-text font-bold'>{t('sso_url')}</span>
</label>
<input
type='text'
className='input-bordered input w-full'
defaultValue={metadata.ssoUrl}
readOnly
/>
</div>
<div className='form-control w-full'>
<label className='label'>
<span className='label-text font-bold'>{t('entity_id')}</span>
</label>
<input
type='text'
className='input-bordered input w-full'
defaultValue={metadata.entityId}
readOnly
/>
</div>
<div className='form-control w-full'>
<label className='label'>
<div className='flex w-full items-center justify-between'>
<span className='label-text font-bold'>{t('x509_certificate')}</span>
<span>
<a
href='/.well-known/saml.cer'
target='_blank'
className='label-text font-bold text-gray-500'>
{t('download')}
</a>
</span>
</div>
</label>
<textarea
className='textarea-bordered textarea w-full'
rows={10}
defaultValue={metadata.x509cert.trim()}
readOnly></textarea>
</div>
</div>
</div>
</div>

View File

@ -52,6 +52,7 @@
"prev": "Prev",
"previous": "Previous",
"product": "Product",
"generate": "Generate",
"regenerate": "Regenerate",
"save_changes": "Save Changes",
"saved": "Saved",

View File

@ -42,10 +42,18 @@ module.exports = {
source: '/.well-known/sp-metadata',
destination: '/api/well-known/sp-metadata',
},
{
source: '/.well-known/idp-metadata',
destination: '/api/well-known/idp-metadata',
},
{
source: '/.well-known/saml-configuration',
destination: '/well-known/saml-configuration',
},
{
source: '/.well-known/idp-configuration',
destination: '/well-known/idp-configuration',
},
{
source: '/oauth/jwks',
destination: '/api/oauth/jwks',

391
npm/package-lock.json generated
View File

@ -29,20 +29,20 @@
},
"devDependencies": {
"@faker-js/faker": "7.6.0",
"@types/node": "18.11.13",
"@types/node": "18.11.15",
"@types/sinon": "10.0.13",
"@types/tap": "15.0.7",
"@typescript-eslint/eslint-plugin": "5.44.0",
"@typescript-eslint/parser": "5.45.1",
"@typescript-eslint/eslint-plugin": "5.46.1",
"@typescript-eslint/parser": "5.46.1",
"cross-env": "7.0.3",
"eslint": "8.28.0",
"eslint": "8.29.0",
"eslint-config-prettier": "8.5.0",
"prettier": "2.8.0",
"sinon": "14.0.2",
"prettier": "2.8.1",
"sinon": "15.0.1",
"tap": "16.3.2",
"ts-node": "10.9.1",
"tsconfig-paths": "4.1.1",
"typescript": "4.9.3"
"typescript": "4.9.4"
},
"engines": {
"node": ">=14.18.1 <=18.x"
@ -1976,21 +1976,12 @@
}
},
"node_modules/@sinonjs/fake-timers": {
"version": "9.1.2",
"resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz",
"integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==",
"version": "10.0.2",
"resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.0.2.tgz",
"integrity": "sha512-SwUDyjWnah1AaNl7kxsa7cfLhlTYoiyhDAIgyh+El30YvXs/o7OLXpYH88Zdhyx9JExKrmHDJ+10bwIcY80Jmw==",
"dev": true,
"dependencies": {
"@sinonjs/commons": "^1.7.0"
}
},
"node_modules/@sinonjs/fake-timers/node_modules/@sinonjs/commons": {
"version": "1.8.5",
"resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.5.tgz",
"integrity": "sha512-rTpCA0wG1wUxglBSFdMMY0oTrKYvgf4fNgv/sXbfCVAdf+FnPBdKJR/7XbpTCwbCrvCbdPYnlWaUUYz4V2fPDA==",
"dev": true,
"dependencies": {
"type-detect": "4.0.8"
"@sinonjs/commons": "^2.0.0"
}
},
"node_modules/@sinonjs/samsam": {
@ -2062,9 +2053,9 @@
"dev": true
},
"node_modules/@types/node": {
"version": "18.11.13",
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.13.tgz",
"integrity": "sha512-IASpMGVcWpUsx5xBOrxMj7Bl8lqfuTY7FKAnPmu5cHkfQVWF8GulWS1jbRqA934qZL35xh5xN/+Xe/i26Bod4w=="
"version": "18.11.15",
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.15.tgz",
"integrity": "sha512-VkhBbVo2+2oozlkdHXLrb3zjsRkpdnaU2bXmX8Wgle3PUi569eLRaHGlgETQHR7lLL1w7GiG3h9SnePhxNDecw=="
},
"node_modules/@types/semver": {
"version": "7.3.13",
@ -2108,14 +2099,14 @@
}
},
"node_modules/@typescript-eslint/eslint-plugin": {
"version": "5.44.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.44.0.tgz",
"integrity": "sha512-j5ULd7FmmekcyWeArx+i8x7sdRHzAtXTkmDPthE4amxZOWKFK7bomoJ4r7PJ8K7PoMzD16U8MmuZFAonr1ERvw==",
"version": "5.46.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.46.1.tgz",
"integrity": "sha512-YpzNv3aayRBwjs4J3oz65eVLXc9xx0PDbIRisHj+dYhvBn02MjYOD96P8YGiWEIFBrojaUjxvkaUpakD82phsA==",
"dev": true,
"dependencies": {
"@typescript-eslint/scope-manager": "5.44.0",
"@typescript-eslint/type-utils": "5.44.0",
"@typescript-eslint/utils": "5.44.0",
"@typescript-eslint/scope-manager": "5.46.1",
"@typescript-eslint/type-utils": "5.46.1",
"@typescript-eslint/utils": "5.46.1",
"debug": "^4.3.4",
"ignore": "^5.2.0",
"natural-compare-lite": "^1.4.0",
@ -2141,14 +2132,14 @@
}
},
"node_modules/@typescript-eslint/parser": {
"version": "5.45.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.45.1.tgz",
"integrity": "sha512-JQ3Ep8bEOXu16q0ztsatp/iQfDCtvap7sp/DKo7DWltUquj5AfCOpX2zSzJ8YkAVnrQNqQ5R62PBz2UtrfmCkA==",
"version": "5.46.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.46.1.tgz",
"integrity": "sha512-RelQ5cGypPh4ySAtfIMBzBGyrNerQcmfA1oJvPj5f+H4jI59rl9xxpn4bonC0tQvUKOEN7eGBFWxFLK3Xepneg==",
"dev": true,
"dependencies": {
"@typescript-eslint/scope-manager": "5.45.1",
"@typescript-eslint/types": "5.45.1",
"@typescript-eslint/typescript-estree": "5.45.1",
"@typescript-eslint/scope-manager": "5.46.1",
"@typescript-eslint/types": "5.46.1",
"@typescript-eslint/typescript-estree": "5.46.1",
"debug": "^4.3.4"
},
"engines": {
@ -2167,88 +2158,14 @@
}
}
},
"node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": {
"version": "5.45.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.45.1.tgz",
"integrity": "sha512-D6fCileR6Iai7E35Eb4Kp+k0iW7F1wxXYrOhX/3dywsOJpJAQ20Fwgcf+P/TDtvQ7zcsWsrJaglaQWDhOMsspQ==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "5.45.1",
"@typescript-eslint/visitor-keys": "5.45.1"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
}
},
"node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": {
"version": "5.45.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.45.1.tgz",
"integrity": "sha512-HEW3U0E5dLjUT+nk7b4lLbOherS1U4ap+b9pfu2oGsW3oPu7genRaY9dDv3nMczC1rbnRY2W/D7SN05wYoGImg==",
"dev": true,
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
}
},
"node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": {
"version": "5.45.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.45.1.tgz",
"integrity": "sha512-76NZpmpCzWVrrb0XmYEpbwOz/FENBi+5W7ipVXAsG3OoFrQKJMiaqsBMbvGRyLtPotGqUfcY7Ur8j0dksDJDng==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "5.45.1",
"@typescript-eslint/visitor-keys": "5.45.1",
"debug": "^4.3.4",
"globby": "^11.1.0",
"is-glob": "^4.0.3",
"semver": "^7.3.7",
"tsutils": "^3.21.0"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependenciesMeta": {
"typescript": {
"optional": true
}
}
},
"node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": {
"version": "5.45.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.45.1.tgz",
"integrity": "sha512-cy9ln+6rmthYWjH9fmx+5FU/JDpjQb586++x2FZlveq7GdGuLLW9a2Jcst2TGekH82bXpfmRNSwP9tyEs6RjvQ==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "5.45.1",
"eslint-visitor-keys": "^3.3.0"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
}
},
"node_modules/@typescript-eslint/scope-manager": {
"version": "5.44.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.44.0.tgz",
"integrity": "sha512-2pKml57KusI0LAhgLKae9kwWeITZ7IsZs77YxyNyIVOwQ1kToyXRaJLl+uDEXzMN5hnobKUOo2gKntK9H1YL8g==",
"version": "5.46.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.46.1.tgz",
"integrity": "sha512-iOChVivo4jpwUdrJZyXSMrEIM/PvsbbDOX1y3UCKjSgWn+W89skxWaYXACQfxmIGhPVpRWK/VWPYc+bad6smIA==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "5.44.0",
"@typescript-eslint/visitor-keys": "5.44.0"
"@typescript-eslint/types": "5.46.1",
"@typescript-eslint/visitor-keys": "5.46.1"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@ -2259,13 +2176,13 @@
}
},
"node_modules/@typescript-eslint/type-utils": {
"version": "5.44.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.44.0.tgz",
"integrity": "sha512-A1u0Yo5wZxkXPQ7/noGkRhV4J9opcymcr31XQtOzcc5nO/IHN2E2TPMECKWYpM3e6olWEM63fq/BaL1wEYnt/w==",
"version": "5.46.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.46.1.tgz",
"integrity": "sha512-V/zMyfI+jDmL1ADxfDxjZ0EMbtiVqj8LUGPAGyBkXXStWmCUErMpW873zEHsyguWCuq2iN4BrlWUkmuVj84yng==",
"dev": true,
"dependencies": {
"@typescript-eslint/typescript-estree": "5.44.0",
"@typescript-eslint/utils": "5.44.0",
"@typescript-eslint/typescript-estree": "5.46.1",
"@typescript-eslint/utils": "5.46.1",
"debug": "^4.3.4",
"tsutils": "^3.21.0"
},
@ -2286,9 +2203,9 @@
}
},
"node_modules/@typescript-eslint/types": {
"version": "5.44.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.44.0.tgz",
"integrity": "sha512-Tp+zDnHmGk4qKR1l+Y1rBvpjpm5tGXX339eAlRBDg+kgZkz9Bw+pqi4dyseOZMsGuSH69fYfPJCBKBrbPCxYFQ==",
"version": "5.46.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.46.1.tgz",
"integrity": "sha512-Z5pvlCaZgU+93ryiYUwGwLl9AQVB/PQ1TsJ9NZ/gHzZjN7g9IAn6RSDkpCV8hqTwAiaj6fmCcKSQeBPlIpW28w==",
"dev": true,
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@ -2299,13 +2216,13 @@
}
},
"node_modules/@typescript-eslint/typescript-estree": {
"version": "5.44.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.44.0.tgz",
"integrity": "sha512-M6Jr+RM7M5zeRj2maSfsZK2660HKAJawv4Ud0xT+yauyvgrsHu276VtXlKDFnEmhG+nVEd0fYZNXGoAgxwDWJw==",
"version": "5.46.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.46.1.tgz",
"integrity": "sha512-j9W4t67QiNp90kh5Nbr1w92wzt+toiIsaVPnEblB2Ih2U9fqBTyqV9T3pYWZBRt6QoMh/zVWP59EpuCjc4VRBg==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "5.44.0",
"@typescript-eslint/visitor-keys": "5.44.0",
"@typescript-eslint/types": "5.46.1",
"@typescript-eslint/visitor-keys": "5.46.1",
"debug": "^4.3.4",
"globby": "^11.1.0",
"is-glob": "^4.0.3",
@ -2326,16 +2243,16 @@
}
},
"node_modules/@typescript-eslint/utils": {
"version": "5.44.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.44.0.tgz",
"integrity": "sha512-fMzA8LLQ189gaBjS0MZszw5HBdZgVwxVFShCO3QN+ws3GlPkcy9YuS3U4wkT6su0w+Byjq3mS3uamy9HE4Yfjw==",
"version": "5.46.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.46.1.tgz",
"integrity": "sha512-RBdBAGv3oEpFojaCYT4Ghn4775pdjvwfDOfQ2P6qzNVgQOVrnSPe5/Pb88kv7xzYQjoio0eKHKB9GJ16ieSxvA==",
"dev": true,
"dependencies": {
"@types/json-schema": "^7.0.9",
"@types/semver": "^7.3.12",
"@typescript-eslint/scope-manager": "5.44.0",
"@typescript-eslint/types": "5.44.0",
"@typescript-eslint/typescript-estree": "5.44.0",
"@typescript-eslint/scope-manager": "5.46.1",
"@typescript-eslint/types": "5.46.1",
"@typescript-eslint/typescript-estree": "5.46.1",
"eslint-scope": "^5.1.1",
"eslint-utils": "^3.0.0",
"semver": "^7.3.7"
@ -2352,12 +2269,12 @@
}
},
"node_modules/@typescript-eslint/visitor-keys": {
"version": "5.44.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.44.0.tgz",
"integrity": "sha512-a48tLG8/4m62gPFbJ27FxwCOqPKxsb8KC3HkmYoq2As/4YyjQl1jDbRr1s63+g4FS/iIehjmN3L5UjmKva1HzQ==",
"version": "5.46.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.46.1.tgz",
"integrity": "sha512-jczZ9noovXwy59KjRTk1OftT78pwygdcmCuBf8yMoWt/8O8l+6x2LSEze0E4TeepXK4MezW3zGSyoDRZK7Y9cg==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "5.44.0",
"@typescript-eslint/types": "5.46.1",
"eslint-visitor-keys": "^3.3.0"
},
"engines": {
@ -3242,9 +3159,9 @@
}
},
"node_modules/eslint": {
"version": "8.28.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.28.0.tgz",
"integrity": "sha512-S27Di+EVyMxcHiwDrFzk8dJYAaD+/5SoWKxL1ri/71CRHsnJnRDPNt2Kzj24+MT9FDupf4aqqyqPrvI8MvQ4VQ==",
"version": "8.29.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.29.0.tgz",
"integrity": "sha512-isQ4EEiyUjZFbEKvEGJKKGBwXtvXX+zJbkVKCgTuB9t/+jUBcy8avhkEwWJecI15BkRkOYmvIM5ynbhRjEkoeg==",
"dev": true,
"dependencies": {
"@eslint/eslintrc": "^1.3.3",
@ -5603,9 +5520,9 @@
}
},
"node_modules/prettier": {
"version": "2.8.0",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.0.tgz",
"integrity": "sha512-9Lmg8hTFZKG0Asr/kW9Bp8tJjRVluO8EJQVfY2T7FMw9T5jy4I/Uvx0Rca/XWf50QQ1/SS48+6IJWnrb+2yemA==",
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.1.tgz",
"integrity": "sha512-lqGoSJBQNJidqCHE80vqZJHWHRFoNYsSpP9AjFhlhi9ODCJA541svILes/+/1GM3VaL/abZi7cpFzOpdR9UPKg==",
"dev": true,
"bin": {
"prettier": "bin-prettier.js"
@ -5946,13 +5863,13 @@
"license": "ISC"
},
"node_modules/sinon": {
"version": "14.0.2",
"resolved": "https://registry.npmjs.org/sinon/-/sinon-14.0.2.tgz",
"integrity": "sha512-PDpV0ZI3ZCS3pEqx0vpNp6kzPhHrLx72wA0G+ZLaaJjLIYeE0n8INlgaohKuGy7hP0as5tbUd23QWu5U233t+w==",
"version": "15.0.1",
"resolved": "https://registry.npmjs.org/sinon/-/sinon-15.0.1.tgz",
"integrity": "sha512-PZXKc08f/wcA/BMRGBze2Wmw50CWPiAH3E21EOi4B49vJ616vW4DQh4fQrqsYox2aNR/N3kCqLuB0PwwOucQrg==",
"dev": true,
"dependencies": {
"@sinonjs/commons": "^2.0.0",
"@sinonjs/fake-timers": "^9.1.2",
"@sinonjs/fake-timers": "10.0.2",
"@sinonjs/samsam": "^7.0.1",
"diff": "^5.0.0",
"nise": "^5.1.2",
@ -8592,9 +8509,9 @@
}
},
"node_modules/typescript": {
"version": "4.9.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.3.tgz",
"integrity": "sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA==",
"version": "4.9.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz",
"integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==",
"dev": true,
"bin": {
"tsc": "bin/tsc",
@ -10502,23 +10419,12 @@
}
},
"@sinonjs/fake-timers": {
"version": "9.1.2",
"resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz",
"integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==",
"version": "10.0.2",
"resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.0.2.tgz",
"integrity": "sha512-SwUDyjWnah1AaNl7kxsa7cfLhlTYoiyhDAIgyh+El30YvXs/o7OLXpYH88Zdhyx9JExKrmHDJ+10bwIcY80Jmw==",
"dev": true,
"requires": {
"@sinonjs/commons": "^1.7.0"
},
"dependencies": {
"@sinonjs/commons": {
"version": "1.8.5",
"resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.5.tgz",
"integrity": "sha512-rTpCA0wG1wUxglBSFdMMY0oTrKYvgf4fNgv/sXbfCVAdf+FnPBdKJR/7XbpTCwbCrvCbdPYnlWaUUYz4V2fPDA==",
"dev": true,
"requires": {
"type-detect": "4.0.8"
}
}
"@sinonjs/commons": "^2.0.0"
}
},
"@sinonjs/samsam": {
@ -10582,9 +10488,9 @@
"dev": true
},
"@types/node": {
"version": "18.11.13",
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.13.tgz",
"integrity": "sha512-IASpMGVcWpUsx5xBOrxMj7Bl8lqfuTY7FKAnPmu5cHkfQVWF8GulWS1jbRqA934qZL35xh5xN/+Xe/i26Bod4w=="
"version": "18.11.15",
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.15.tgz",
"integrity": "sha512-VkhBbVo2+2oozlkdHXLrb3zjsRkpdnaU2bXmX8Wgle3PUi569eLRaHGlgETQHR7lLL1w7GiG3h9SnePhxNDecw=="
},
"@types/semver": {
"version": "7.3.13",
@ -10625,14 +10531,14 @@
}
},
"@typescript-eslint/eslint-plugin": {
"version": "5.44.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.44.0.tgz",
"integrity": "sha512-j5ULd7FmmekcyWeArx+i8x7sdRHzAtXTkmDPthE4amxZOWKFK7bomoJ4r7PJ8K7PoMzD16U8MmuZFAonr1ERvw==",
"version": "5.46.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.46.1.tgz",
"integrity": "sha512-YpzNv3aayRBwjs4J3oz65eVLXc9xx0PDbIRisHj+dYhvBn02MjYOD96P8YGiWEIFBrojaUjxvkaUpakD82phsA==",
"dev": true,
"requires": {
"@typescript-eslint/scope-manager": "5.44.0",
"@typescript-eslint/type-utils": "5.44.0",
"@typescript-eslint/utils": "5.44.0",
"@typescript-eslint/scope-manager": "5.46.1",
"@typescript-eslint/type-utils": "5.46.1",
"@typescript-eslint/utils": "5.46.1",
"debug": "^4.3.4",
"ignore": "^5.2.0",
"natural-compare-lite": "^1.4.0",
@ -10642,96 +10548,53 @@
}
},
"@typescript-eslint/parser": {
"version": "5.45.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.45.1.tgz",
"integrity": "sha512-JQ3Ep8bEOXu16q0ztsatp/iQfDCtvap7sp/DKo7DWltUquj5AfCOpX2zSzJ8YkAVnrQNqQ5R62PBz2UtrfmCkA==",
"version": "5.46.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.46.1.tgz",
"integrity": "sha512-RelQ5cGypPh4ySAtfIMBzBGyrNerQcmfA1oJvPj5f+H4jI59rl9xxpn4bonC0tQvUKOEN7eGBFWxFLK3Xepneg==",
"dev": true,
"requires": {
"@typescript-eslint/scope-manager": "5.45.1",
"@typescript-eslint/types": "5.45.1",
"@typescript-eslint/typescript-estree": "5.45.1",
"@typescript-eslint/scope-manager": "5.46.1",
"@typescript-eslint/types": "5.46.1",
"@typescript-eslint/typescript-estree": "5.46.1",
"debug": "^4.3.4"
},
"dependencies": {
"@typescript-eslint/scope-manager": {
"version": "5.45.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.45.1.tgz",
"integrity": "sha512-D6fCileR6Iai7E35Eb4Kp+k0iW7F1wxXYrOhX/3dywsOJpJAQ20Fwgcf+P/TDtvQ7zcsWsrJaglaQWDhOMsspQ==",
"dev": true,
"requires": {
"@typescript-eslint/types": "5.45.1",
"@typescript-eslint/visitor-keys": "5.45.1"
}
},
"@typescript-eslint/types": {
"version": "5.45.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.45.1.tgz",
"integrity": "sha512-HEW3U0E5dLjUT+nk7b4lLbOherS1U4ap+b9pfu2oGsW3oPu7genRaY9dDv3nMczC1rbnRY2W/D7SN05wYoGImg==",
"dev": true
},
"@typescript-eslint/typescript-estree": {
"version": "5.45.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.45.1.tgz",
"integrity": "sha512-76NZpmpCzWVrrb0XmYEpbwOz/FENBi+5W7ipVXAsG3OoFrQKJMiaqsBMbvGRyLtPotGqUfcY7Ur8j0dksDJDng==",
"dev": true,
"requires": {
"@typescript-eslint/types": "5.45.1",
"@typescript-eslint/visitor-keys": "5.45.1",
"debug": "^4.3.4",
"globby": "^11.1.0",
"is-glob": "^4.0.3",
"semver": "^7.3.7",
"tsutils": "^3.21.0"
}
},
"@typescript-eslint/visitor-keys": {
"version": "5.45.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.45.1.tgz",
"integrity": "sha512-cy9ln+6rmthYWjH9fmx+5FU/JDpjQb586++x2FZlveq7GdGuLLW9a2Jcst2TGekH82bXpfmRNSwP9tyEs6RjvQ==",
"dev": true,
"requires": {
"@typescript-eslint/types": "5.45.1",
"eslint-visitor-keys": "^3.3.0"
}
}
}
},
"@typescript-eslint/scope-manager": {
"version": "5.44.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.44.0.tgz",
"integrity": "sha512-2pKml57KusI0LAhgLKae9kwWeITZ7IsZs77YxyNyIVOwQ1kToyXRaJLl+uDEXzMN5hnobKUOo2gKntK9H1YL8g==",
"version": "5.46.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.46.1.tgz",
"integrity": "sha512-iOChVivo4jpwUdrJZyXSMrEIM/PvsbbDOX1y3UCKjSgWn+W89skxWaYXACQfxmIGhPVpRWK/VWPYc+bad6smIA==",
"dev": true,
"requires": {
"@typescript-eslint/types": "5.44.0",
"@typescript-eslint/visitor-keys": "5.44.0"
"@typescript-eslint/types": "5.46.1",
"@typescript-eslint/visitor-keys": "5.46.1"
}
},
"@typescript-eslint/type-utils": {
"version": "5.44.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.44.0.tgz",
"integrity": "sha512-A1u0Yo5wZxkXPQ7/noGkRhV4J9opcymcr31XQtOzcc5nO/IHN2E2TPMECKWYpM3e6olWEM63fq/BaL1wEYnt/w==",
"version": "5.46.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.46.1.tgz",
"integrity": "sha512-V/zMyfI+jDmL1ADxfDxjZ0EMbtiVqj8LUGPAGyBkXXStWmCUErMpW873zEHsyguWCuq2iN4BrlWUkmuVj84yng==",
"dev": true,
"requires": {
"@typescript-eslint/typescript-estree": "5.44.0",
"@typescript-eslint/utils": "5.44.0",
"@typescript-eslint/typescript-estree": "5.46.1",
"@typescript-eslint/utils": "5.46.1",
"debug": "^4.3.4",
"tsutils": "^3.21.0"
}
},
"@typescript-eslint/types": {
"version": "5.44.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.44.0.tgz",
"integrity": "sha512-Tp+zDnHmGk4qKR1l+Y1rBvpjpm5tGXX339eAlRBDg+kgZkz9Bw+pqi4dyseOZMsGuSH69fYfPJCBKBrbPCxYFQ==",
"version": "5.46.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.46.1.tgz",
"integrity": "sha512-Z5pvlCaZgU+93ryiYUwGwLl9AQVB/PQ1TsJ9NZ/gHzZjN7g9IAn6RSDkpCV8hqTwAiaj6fmCcKSQeBPlIpW28w==",
"dev": true
},
"@typescript-eslint/typescript-estree": {
"version": "5.44.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.44.0.tgz",
"integrity": "sha512-M6Jr+RM7M5zeRj2maSfsZK2660HKAJawv4Ud0xT+yauyvgrsHu276VtXlKDFnEmhG+nVEd0fYZNXGoAgxwDWJw==",
"version": "5.46.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.46.1.tgz",
"integrity": "sha512-j9W4t67QiNp90kh5Nbr1w92wzt+toiIsaVPnEblB2Ih2U9fqBTyqV9T3pYWZBRt6QoMh/zVWP59EpuCjc4VRBg==",
"dev": true,
"requires": {
"@typescript-eslint/types": "5.44.0",
"@typescript-eslint/visitor-keys": "5.44.0",
"@typescript-eslint/types": "5.46.1",
"@typescript-eslint/visitor-keys": "5.46.1",
"debug": "^4.3.4",
"globby": "^11.1.0",
"is-glob": "^4.0.3",
@ -10740,28 +10603,28 @@
}
},
"@typescript-eslint/utils": {
"version": "5.44.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.44.0.tgz",
"integrity": "sha512-fMzA8LLQ189gaBjS0MZszw5HBdZgVwxVFShCO3QN+ws3GlPkcy9YuS3U4wkT6su0w+Byjq3mS3uamy9HE4Yfjw==",
"version": "5.46.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.46.1.tgz",
"integrity": "sha512-RBdBAGv3oEpFojaCYT4Ghn4775pdjvwfDOfQ2P6qzNVgQOVrnSPe5/Pb88kv7xzYQjoio0eKHKB9GJ16ieSxvA==",
"dev": true,
"requires": {
"@types/json-schema": "^7.0.9",
"@types/semver": "^7.3.12",
"@typescript-eslint/scope-manager": "5.44.0",
"@typescript-eslint/types": "5.44.0",
"@typescript-eslint/typescript-estree": "5.44.0",
"@typescript-eslint/scope-manager": "5.46.1",
"@typescript-eslint/types": "5.46.1",
"@typescript-eslint/typescript-estree": "5.46.1",
"eslint-scope": "^5.1.1",
"eslint-utils": "^3.0.0",
"semver": "^7.3.7"
}
},
"@typescript-eslint/visitor-keys": {
"version": "5.44.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.44.0.tgz",
"integrity": "sha512-a48tLG8/4m62gPFbJ27FxwCOqPKxsb8KC3HkmYoq2As/4YyjQl1jDbRr1s63+g4FS/iIehjmN3L5UjmKva1HzQ==",
"version": "5.46.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.46.1.tgz",
"integrity": "sha512-jczZ9noovXwy59KjRTk1OftT78pwygdcmCuBf8yMoWt/8O8l+6x2LSEze0E4TeepXK4MezW3zGSyoDRZK7Y9cg==",
"dev": true,
"requires": {
"@typescript-eslint/types": "5.44.0",
"@typescript-eslint/types": "5.46.1",
"eslint-visitor-keys": "^3.3.0"
}
},
@ -11303,9 +11166,9 @@
"dev": true
},
"eslint": {
"version": "8.28.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.28.0.tgz",
"integrity": "sha512-S27Di+EVyMxcHiwDrFzk8dJYAaD+/5SoWKxL1ri/71CRHsnJnRDPNt2Kzj24+MT9FDupf4aqqyqPrvI8MvQ4VQ==",
"version": "8.29.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.29.0.tgz",
"integrity": "sha512-isQ4EEiyUjZFbEKvEGJKKGBwXtvXX+zJbkVKCgTuB9t/+jUBcy8avhkEwWJecI15BkRkOYmvIM5ynbhRjEkoeg==",
"dev": true,
"requires": {
"@eslint/eslintrc": "^1.3.3",
@ -12882,9 +12745,9 @@
"dev": true
},
"prettier": {
"version": "2.8.0",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.0.tgz",
"integrity": "sha512-9Lmg8hTFZKG0Asr/kW9Bp8tJjRVluO8EJQVfY2T7FMw9T5jy4I/Uvx0Rca/XWf50QQ1/SS48+6IJWnrb+2yemA==",
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.1.tgz",
"integrity": "sha512-lqGoSJBQNJidqCHE80vqZJHWHRFoNYsSpP9AjFhlhi9ODCJA541svILes/+/1GM3VaL/abZi7cpFzOpdR9UPKg==",
"dev": true
},
"process-on-spawn": {
@ -13082,13 +12945,13 @@
"dev": true
},
"sinon": {
"version": "14.0.2",
"resolved": "https://registry.npmjs.org/sinon/-/sinon-14.0.2.tgz",
"integrity": "sha512-PDpV0ZI3ZCS3pEqx0vpNp6kzPhHrLx72wA0G+ZLaaJjLIYeE0n8INlgaohKuGy7hP0as5tbUd23QWu5U233t+w==",
"version": "15.0.1",
"resolved": "https://registry.npmjs.org/sinon/-/sinon-15.0.1.tgz",
"integrity": "sha512-PZXKc08f/wcA/BMRGBze2Wmw50CWPiAH3E21EOi4B49vJ616vW4DQh4fQrqsYox2aNR/N3kCqLuB0PwwOucQrg==",
"dev": true,
"requires": {
"@sinonjs/commons": "^2.0.0",
"@sinonjs/fake-timers": "^9.1.2",
"@sinonjs/fake-timers": "10.0.2",
"@sinonjs/samsam": "^7.0.1",
"diff": "^5.0.0",
"nise": "^5.1.2",
@ -14764,9 +14627,9 @@
}
},
"typescript": {
"version": "4.9.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.3.tgz",
"integrity": "sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA==",
"version": "4.9.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz",
"integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==",
"dev": true
},
"unbox-primitive": {

View File

@ -60,20 +60,20 @@
},
"devDependencies": {
"@faker-js/faker": "7.6.0",
"@types/node": "18.11.13",
"@types/node": "18.11.15",
"@types/sinon": "10.0.13",
"@types/tap": "15.0.7",
"@typescript-eslint/eslint-plugin": "5.44.0",
"@typescript-eslint/parser": "5.45.1",
"@typescript-eslint/eslint-plugin": "5.46.1",
"@typescript-eslint/parser": "5.46.1",
"cross-env": "7.0.3",
"eslint": "8.28.0",
"eslint": "8.29.0",
"eslint-config-prettier": "8.5.0",
"prettier": "2.8.0",
"sinon": "14.0.2",
"prettier": "2.8.1",
"sinon": "15.0.1",
"tap": "16.3.2",
"ts-node": "10.9.1",
"tsconfig-paths": "4.1.1",
"typescript": "4.9.3"
"typescript": "4.9.4"
},
"engines": {
"node": ">=14.18.1 <=18.x"

View File

@ -1,6 +1,6 @@
import { ApiResponse, ISetupLinkController, SetupLink, SetupLinkCreatePayload, Storable } from '../typings';
import * as dbutils from '../db/utils';
import { IndexNames } from './utils';
import { IndexNames, validateTenantAndProduct } from './utils';
import crypto from 'crypto';
export class SetupLinkController implements ISetupLinkController {
@ -11,6 +11,9 @@ export class SetupLinkController implements ISetupLinkController {
}
async create(body: SetupLinkCreatePayload): Promise<ApiResponse<SetupLink>> {
const { tenant, product, service, regenerate } = body;
validateTenantAndProduct(tenant, product);
const setupID = dbutils.keyDigest(dbutils.keyFromParts(tenant, product, service));
const token = crypto.randomBytes(24).toString('hex');
const val = {

View File

@ -134,9 +134,7 @@ export class App {
}
// Get the metadata for the app
public async getMetadata(id: string): Promise<Pick<SAMLFederationAppWithMetadata, 'metadata'>['metadata']> {
await this.get(id);
public async getMetadata(): Promise<Pick<SAMLFederationAppWithMetadata, 'metadata'>['metadata']> {
const { publicKey } = await getDefaultCertificate();
const ssoUrl = `${this.opts.externalUrl}/api/federated-saml/sso`;

7217
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -55,13 +55,13 @@
"@tailwindcss/typography": "0.5.8",
"classnames": "2.3.2",
"cors": "2.8.5",
"daisyui": "2.39.1",
"daisyui": "2.45.0",
"micromatch": "4.0.5",
"next": "13.0.6",
"next-auth": "4.18.0",
"next": "13.0.7",
"next-auth": "4.18.6",
"next-i18next": "12.1.0",
"next-mdx-remote": "4.1.0",
"node-fetch": "3.2.10",
"next-mdx-remote": "4.2.0",
"node-fetch": "3.3.0",
"nodemailer": "6.8.0",
"raw-body": "2.5.1",
"react": "18.2.0",
@ -73,27 +73,27 @@
},
"devDependencies": {
"@apidevtools/swagger-cli": "4.0.4",
"@babel/plugin-proposal-decorators": "7.20.0",
"@babel/plugin-proposal-decorators": "7.20.5",
"@playwright/test": "1.28.1",
"@types/cors": "2.8.12",
"@types/cors": "2.8.13",
"@types/micromatch": "4.0.2",
"@types/node": "18.11.9",
"@types/node": "18.11.15",
"@types/react": "18.0.26",
"@typescript-eslint/eslint-plugin": "5.43.0",
"@typescript-eslint/parser": "5.46.0",
"@typescript-eslint/eslint-plugin": "5.46.1",
"@typescript-eslint/parser": "5.46.1",
"autoprefixer": "10.4.13",
"cross-env": "7.0.3",
"env-cmd": "10.1.0",
"eslint": "8.27.0",
"eslint-config-next": "13.0.0",
"eslint": "8.29.0",
"eslint-config-next": "13.0.7",
"eslint-config-prettier": "8.5.0",
"husky": "8.0.2",
"lint-staged": "13.1.0",
"postcss": "8.4.19",
"postcss": "8.4.20",
"prettier": "2.8.1",
"prettier-plugin-tailwindcss": "0.2.0",
"prettier-plugin-tailwindcss": "0.2.1",
"swagger-jsdoc": "6.2.5",
"tailwindcss": "3.2.1",
"tailwindcss": "3.2.4",
"ts-node": "10.9.1",
"tsconfig-paths": "4.1.1",
"typescript": "4.9.4"

View File

@ -16,6 +16,7 @@ const unauthenticatedRoutes = [
'/',
'/admin/auth/login',
'/well-known/saml-configuration',
'/well-known/idp-configuration',
'/oauth/jwks',
'/idp/select',
'/error',
@ -37,7 +38,7 @@ function MyApp({ Component, pageProps }: AppPropsWithLayout) {
return (
<>
{getLayout(<Component {...props} />)}
<Toaster toastOptions={{ duration: Infinity }} />
<Toaster toastOptions={{ duration: 10000 }} />
</>
);
}
@ -46,7 +47,7 @@ function MyApp({ Component, pageProps }: AppPropsWithLayout) {
return (
<SetupLayout>
<Component {...props} />
<Toaster toastOptions={{ duration: Infinity }} />
<Toaster toastOptions={{ duration: 10000 }} />
</SetupLayout>
);
}

View File

@ -3,18 +3,25 @@ import jackson from '@lib/jackson';
import { checkSession } from '@lib/middleware';
export const handler = async (req: NextApiRequest, res: NextApiResponse) => {
const { method } = req;
try {
const { method } = req;
switch (method) {
case 'POST':
return handlePOST(req, res);
case 'GET':
return handleGET(req, res);
case 'DELETE':
return handleDELETE(req, res);
default:
res.setHeader('Allow', ['GET']);
res.status(405).json({ data: null, error: { message: `Method ${method} Not Allowed` } });
switch (method) {
case 'POST':
await handlePOST(req, res);
return;
case 'GET':
await handleGET(req, res);
return;
case 'DELETE':
await handleDELETE(req, res);
return;
default:
res.setHeader('Allow', ['GET']);
res.status(405).json({ data: null, error: { message: `Method ${method} Not Allowed` } });
}
} catch (error: any) {
res.status(500).json({ data: null, error: { message: error.message || 'Unknown error' } });
}
};

View File

@ -1,11 +1,17 @@
import { serverSideTranslations } from 'next-i18next/serverSideTranslations';
import jackson from '@lib/jackson';
export { default } from 'ee/federated-saml/pages/metadata';
export async function getServerSideProps({ locale }) {
const { samlFederatedController } = await jackson();
const metadata = await samlFederatedController.app.getMetadata();
return {
props: {
...(await serverSideTranslations(locale, ['common'])),
metadata,
},
};
}