mirror of https://github.com/boxyhq/jackson.git
Compare commits
22 Commits
f65eb0732e
...
0e96fe5521
Author | SHA1 | Date |
---|---|---|
Deepak Prabhakara | 0e96fe5521 | |
dependabot[bot] | 7022aa68e1 | |
dependabot[bot] | 49c611a09a | |
dependabot[bot] | a8c14dec7a | |
dependabot[bot] | 3ee670f057 | |
dependabot[bot] | 044f452945 | |
ukrocks007 | c7272dae67 | |
Deepak Prabhakara | e3ead0cdc8 | |
Deepak Prabhakara | 0439806021 | |
Deepak Prabhakara | 003d602d7d | |
Deepak Prabhakara | d4951f6f20 | |
Deepak Prabhakara | 382f2d6245 | |
Deepak Prabhakara | 08a9b6a28c | |
Deepak Prabhakara | a74dcfd9bb | |
Deepak Prabhakara | 2483827a7a | |
Deepak Prabhakara | b2a6ae5e67 | |
Deepak Prabhakara | a4ff7cebb0 | |
Deepak Prabhakara | 7658fcfa8e | |
Deepak Prabhakara | e5b068cb9e | |
Deepak Prabhakara | eedb1c91e6 | |
Deepak Prabhakara | 3e33d7415b | |
Deepak Prabhakara | 0aaa8f5762 |
|
@ -40,7 +40,7 @@ export const Sidebar = ({ isOpen, setIsOpen }: SidebarProps) => {
|
|||
href: '/admin/sso-connection',
|
||||
text: t('enterprise_sso'),
|
||||
icon: SSOLogo,
|
||||
active: asPath.includes('/admin/sso-connection') || asPath.includes('/admin/federated-saml'),
|
||||
active: asPath.includes('/admin/sso-connection'),
|
||||
items: [
|
||||
{
|
||||
href: '/admin/sso-connection',
|
||||
|
@ -54,14 +54,22 @@ export const Sidebar = ({ isOpen, setIsOpen }: SidebarProps) => {
|
|||
active: asPath.includes('/admin/sso-connection/setup-link'),
|
||||
},
|
||||
{
|
||||
href: '/admin/federated-saml',
|
||||
text: t('saml_federation'),
|
||||
active: asPath.includes('/admin/federated-saml'),
|
||||
},
|
||||
{
|
||||
href: '/admin/sso-tracer',
|
||||
href: '/admin/sso-traces',
|
||||
text: t('bui-tracer-title'),
|
||||
active: asPath.includes('/admin/sso-tracer'),
|
||||
active: asPath.includes('/admin/sso-traces'),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
href: '/admin/identity-federation',
|
||||
text: t('identity_federation'),
|
||||
icon: SSOLogo,
|
||||
active: asPath.includes('/admin/identity-federation'),
|
||||
items: [
|
||||
{
|
||||
href: '/admin/identity-federation',
|
||||
text: t('apps'),
|
||||
active: asPath.includes('/admin/identity-federation'),
|
||||
},
|
||||
],
|
||||
},
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { test, expect } from '@playwright/test';
|
||||
import { SAMLFederationApp } from '@boxyhq/saml-jackson';
|
||||
import { IdentityFederationApp } from '@boxyhq/saml-jackson';
|
||||
|
||||
test.use({
|
||||
extraHTTPHeaders: {
|
||||
|
@ -17,10 +17,10 @@ const expectedApp = {
|
|||
acsUrl: 'https://boxyhq.com/acs',
|
||||
};
|
||||
|
||||
let app = {} as SAMLFederationApp;
|
||||
let app = {} as IdentityFederationApp;
|
||||
|
||||
test.beforeAll(async ({ request }) => {
|
||||
const response = await request.post('/api/v1/federated-saml', {
|
||||
const response = await request.post('/api/v1/identity-federation', {
|
||||
data: {
|
||||
...expectedApp,
|
||||
},
|
||||
|
@ -32,9 +32,9 @@ test.beforeAll(async ({ request }) => {
|
|||
expect(response.status()).toBe(201);
|
||||
});
|
||||
|
||||
test.describe('GET /api/v1/federated-saml', () => {
|
||||
test.describe('GET /api/v1/identity-federation', () => {
|
||||
test('Fetch app by id', async ({ request }) => {
|
||||
const response = await request.get(`/api/v1/federated-saml?id=${app?.id}`);
|
||||
const response = await request.get(`/api/v1/identity-federation?id=${app?.id}`);
|
||||
|
||||
const { data } = await response.json();
|
||||
|
||||
|
@ -45,7 +45,7 @@ test.describe('GET /api/v1/federated-saml', () => {
|
|||
|
||||
test('Fetch app by tenant and product', async ({ request }) => {
|
||||
const response = await request.get(
|
||||
`/api/v1/federated-saml?tenant=${app?.tenant}&product=${app?.product}`
|
||||
`/api/v1/identity-federation?tenant=${app?.tenant}&product=${app?.product}`
|
||||
);
|
||||
|
||||
const { data } = await response.json();
|
||||
|
@ -56,7 +56,7 @@ test.describe('GET /api/v1/federated-saml', () => {
|
|||
});
|
||||
|
||||
test('Fetch app by product', async ({ request }) => {
|
||||
const response = await request.get(`/api/v1/federated-saml/product?product=${app?.product}`);
|
||||
const response = await request.get(`/api/v1/identity-federation/product?product=${app?.product}`);
|
||||
|
||||
const { data } = await response.json();
|
||||
|
||||
|
@ -66,9 +66,9 @@ test.describe('GET /api/v1/federated-saml', () => {
|
|||
});
|
||||
});
|
||||
|
||||
test.describe('PATCH /api/v1/federated-saml', () => {
|
||||
test.describe('PATCH /api/v1/identity-federation', () => {
|
||||
test('Update app by id', async ({ request }) => {
|
||||
const response = await request.patch(`/api/v1/federated-saml`, {
|
||||
const response = await request.patch(`/api/v1/identity-federation`, {
|
||||
data: {
|
||||
id: app?.id,
|
||||
name: 'Updated App',
|
||||
|
@ -86,7 +86,7 @@ test.describe('PATCH /api/v1/federated-saml', () => {
|
|||
});
|
||||
|
||||
test('Update app by tenant and product', async ({ request }) => {
|
||||
const response = await request.patch(`/api/v1/federated-saml`, {
|
||||
const response = await request.patch(`/api/v1/identity-federation`, {
|
||||
data: {
|
||||
id: app?.id,
|
||||
name: 'Updated App 2',
|
||||
|
@ -104,9 +104,9 @@ test.describe('PATCH /api/v1/federated-saml', () => {
|
|||
});
|
||||
});
|
||||
|
||||
test.describe('DELETE /api/v1/federated-saml', () => {
|
||||
test.describe('DELETE /api/v1/identity-federation', () => {
|
||||
test('Delete app by id', async ({ request }) => {
|
||||
const response = await request.delete(`/api/v1/federated-saml?id=${app?.id}`);
|
||||
const response = await request.delete(`/api/v1/identity-federation?id=${app?.id}`);
|
||||
|
||||
const { data } = await response.json();
|
||||
|
||||
|
@ -115,7 +115,7 @@ test.describe('DELETE /api/v1/federated-saml', () => {
|
|||
expect(data).toMatchObject({});
|
||||
|
||||
// Confirm app is deleted
|
||||
const response2 = await request.get(`/api/v1/federated-saml?id=${app?.id}`);
|
||||
const response2 = await request.get(`/api/v1/identity-federation?id=${app?.id}`);
|
||||
|
||||
expect(response2.ok()).toBe(false);
|
||||
expect(response2.status()).toBe(404);
|
|
@ -18,19 +18,19 @@ const UpdateApp = ({ hasValidLicense }: { hasValidLicense: boolean }) => {
|
|||
|
||||
return (
|
||||
<div className='space-y-4'>
|
||||
<LinkBack href='/admin/federated-saml' />
|
||||
<LinkBack href='/admin/identity-federation' />
|
||||
<EditFederatedSAMLApp
|
||||
urls={{
|
||||
getApp: `/api/admin/federated-saml/${id}`,
|
||||
updateApp: `/api/admin/federated-saml/${id}`,
|
||||
deleteApp: `/api/admin/federated-saml/${id}`,
|
||||
getApp: `/api/admin/identity-federation/${id}`,
|
||||
updateApp: `/api/admin/identity-federation/${id}`,
|
||||
deleteApp: `/api/admin/identity-federation/${id}`,
|
||||
}}
|
||||
onUpdate={() => {
|
||||
successToast(t('saml_federation_update_success'));
|
||||
}}
|
||||
onDelete={() => {
|
||||
successToast(t('saml_federation_delete_success'));
|
||||
router.push('/admin/federated-saml');
|
||||
router.push('/admin/identity-federation');
|
||||
}}
|
||||
onError={(error) => {
|
||||
errorToast(error.message);
|
|
@ -9,10 +9,10 @@ const AppsList = ({ hasValidLicense }: { hasValidLicense: boolean }) => {
|
|||
|
||||
return (
|
||||
<FederatedSAMLApps
|
||||
urls={{ getApps: '/api/admin/federated-saml' }}
|
||||
onEdit={(app) => router.push(`/admin/federated-saml/${app.id}/edit`)}
|
||||
urls={{ getApps: '/api/admin/identity-federation' }}
|
||||
onEdit={(app) => router.push(`/admin/identity-federation/${app.id}/edit`)}
|
||||
actions={{
|
||||
newApp: '/admin/federated-saml/new',
|
||||
newApp: '/admin/identity-federation/new',
|
||||
samlConfiguration: '/.well-known/idp-configuration',
|
||||
oidcConfiguration: '/.well-known/openid-configuration',
|
||||
}}
|
|
@ -1,12 +1,12 @@
|
|||
import Link from 'next/link';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import type { SAMLFederationAppWithMetadata } from '@boxyhq/saml-jackson';
|
||||
import type { IdentityFederationAppWithMetadata } from '@boxyhq/saml-jackson';
|
||||
import { Toaster } from '@components/Toaster';
|
||||
import { InputWithCopyButton, CopyToClipboardButton, LinkOutline } from '@boxyhq/internal-ui';
|
||||
import LicenseRequired from '@components/LicenseRequired';
|
||||
|
||||
type MetadataProps = {
|
||||
metadata: Pick<SAMLFederationAppWithMetadata, 'metadata'>['metadata'];
|
||||
metadata: Pick<IdentityFederationAppWithMetadata, 'metadata'>['metadata'];
|
||||
hasValidLicense: boolean;
|
||||
};
|
||||
|
|
@ -16,12 +16,12 @@ const NewApp = ({ hasValidLicense, samlAudience }: { hasValidLicense: boolean; s
|
|||
|
||||
return (
|
||||
<div className='space-y-4'>
|
||||
<LinkBack href='/admin/federated-saml' />
|
||||
<LinkBack href='/admin/identity-federation' />
|
||||
<NewFederatedSAMLApp
|
||||
urls={{ createApp: '/api/admin/federated-saml' }}
|
||||
urls={{ createApp: '/api/admin/identity-federation' }}
|
||||
onSuccess={(data) => {
|
||||
successToast(t('saml_federation_new_success'));
|
||||
router.replace(`/admin/federated-saml/${data.id}/edit`);
|
||||
router.replace(`/admin/identity-federation/${data.id}/edit`);
|
||||
}}
|
||||
onError={(error) => {
|
||||
errorToast(error.message);
|
|
@ -8,12 +8,11 @@
|
|||
"name": "@boxyhq/internal-ui",
|
||||
"version": "0.0.0",
|
||||
"dependencies": {
|
||||
"@rollup/rollup-linux-x64-gnu": "4.17.2",
|
||||
"vite-tsconfig-paths": "4.3.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@rollup/plugin-typescript": "11.1.6",
|
||||
"@types/node": "20.12.7",
|
||||
"@types/node": "20.12.8",
|
||||
"@types/react": "18.3.1",
|
||||
"@typescript-eslint/eslint-plugin": "7.8.0",
|
||||
"@typescript-eslint/parser": "7.8.0",
|
||||
|
@ -1611,9 +1610,10 @@
|
|||
"dev": true
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "20.12.7",
|
||||
"version": "20.12.8",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.8.tgz",
|
||||
"integrity": "sha512-NU0rJLJnshZWdE/097cdCBbyW1h4hEg0xpovcoAQYHl8dnEyp/NAOiE45pvc+Bd1Dt+2r94v2eGFpQJ4R7g+2w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"undici-types": "~5.26.4"
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@rollup/plugin-typescript": "11.1.6",
|
||||
"@types/node": "20.12.7",
|
||||
"@types/node": "20.12.8",
|
||||
"@types/react": "18.3.1",
|
||||
"@typescript-eslint/eslint-plugin": "7.8.0",
|
||||
"@typescript-eslint/parser": "7.8.0",
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
export { NewFederatedSAMLApp } from './NewFederatedSAMLApp';
|
||||
export { EditFederatedSAMLApp } from './EditFederatedSAMLApp';
|
||||
export { FederatedSAMLApps } from './FederatedSAMLApps';
|
|
@ -1,6 +1,6 @@
|
|||
import { useState } from 'react';
|
||||
import { Button } from 'react-daisyui';
|
||||
import type { SAMLFederationApp } from '../types';
|
||||
import type { IdentityFederationApp } from '../types';
|
||||
import TagsInput from 'react-tagsinput';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { useFormik } from 'formik';
|
||||
|
@ -13,7 +13,7 @@ import { ItemList } from '@boxyhq/react-ui/shared';
|
|||
import { CopyToClipboardButton } from '../shared/InputWithCopyButton';
|
||||
import { IconButton } from '../shared/IconButton';
|
||||
|
||||
type EditApp = Pick<SAMLFederationApp, 'name' | 'acsUrl' | 'tenants' | 'redirectUrl'>;
|
||||
type EditApp = Pick<IdentityFederationApp, 'name' | 'acsUrl' | 'tenants' | 'redirectUrl'>;
|
||||
|
||||
export const Edit = ({
|
||||
app,
|
||||
|
@ -22,9 +22,9 @@ export const Edit = ({
|
|||
onUpdate,
|
||||
excludeFields,
|
||||
}: {
|
||||
app: SAMLFederationApp;
|
||||
app: IdentityFederationApp;
|
||||
urls: { patch: string };
|
||||
onUpdate?: (data: SAMLFederationApp) => void;
|
||||
onUpdate?: (data: IdentityFederationApp) => void;
|
||||
onError?: (error: Error) => void;
|
||||
excludeFields?: 'product'[];
|
||||
}) => {
|
|
@ -1,12 +1,12 @@
|
|||
import { Button } from 'react-daisyui';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import type { SAMLFederationApp } from '../types';
|
||||
import type { IdentityFederationApp } from '../types';
|
||||
import { useFormik } from 'formik';
|
||||
import { defaultHeaders } from '../utils';
|
||||
import { Card } from '../shared';
|
||||
import { AttributesMapping } from './AttributesMapping';
|
||||
|
||||
type Mappings = Pick<SAMLFederationApp, 'mappings'>;
|
||||
type Mappings = Pick<IdentityFederationApp, 'mappings'>;
|
||||
|
||||
export const EditAttributesMapping = ({
|
||||
app,
|
||||
|
@ -14,9 +14,9 @@ export const EditAttributesMapping = ({
|
|||
onUpdate,
|
||||
onError,
|
||||
}: {
|
||||
app: SAMLFederationApp;
|
||||
app: IdentityFederationApp;
|
||||
urls: { patch: string };
|
||||
onUpdate?: (data: SAMLFederationApp) => void;
|
||||
onUpdate?: (data: IdentityFederationApp) => void;
|
||||
onError?: (error: Error) => void;
|
||||
}) => {
|
||||
const { t } = useTranslation('common');
|
|
@ -1,11 +1,11 @@
|
|||
import { Button } from 'react-daisyui';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import type { SAMLFederationApp } from '../types';
|
||||
import type { IdentityFederationApp } from '../types';
|
||||
import { useFormik } from 'formik';
|
||||
import { defaultHeaders } from '../utils';
|
||||
import { Card } from '../shared';
|
||||
|
||||
type Branding = Pick<SAMLFederationApp, 'logoUrl' | 'faviconUrl' | 'primaryColor'>;
|
||||
type Branding = Pick<IdentityFederationApp, 'logoUrl' | 'faviconUrl' | 'primaryColor'>;
|
||||
|
||||
export const EditBranding = ({
|
||||
app,
|
||||
|
@ -13,9 +13,9 @@ export const EditBranding = ({
|
|||
onUpdate,
|
||||
onError,
|
||||
}: {
|
||||
app: SAMLFederationApp;
|
||||
app: IdentityFederationApp;
|
||||
urls: { patch: string };
|
||||
onUpdate?: (data: SAMLFederationApp) => void;
|
||||
onUpdate?: (data: IdentityFederationApp) => void;
|
||||
onError?: (error: Error) => void;
|
||||
}) => {
|
||||
const { t } = useTranslation('common');
|
|
@ -1,5 +1,5 @@
|
|||
import useSWR from 'swr';
|
||||
import type { SAMLFederationApp } from '../types';
|
||||
import type { IdentityFederationApp } from '../types';
|
||||
import { EditBranding } from './EditBranding';
|
||||
import { Edit } from './Edit';
|
||||
import { EditAttributesMapping } from './EditAttributesMapping';
|
||||
|
@ -9,7 +9,7 @@ import { useEffect, useState } from 'react';
|
|||
import { defaultHeaders, fetcher } from '../utils';
|
||||
import { PageHeader } from '../shared';
|
||||
|
||||
export const EditFederatedSAMLApp = ({
|
||||
export const EditIdentityFederationApp = ({
|
||||
urls,
|
||||
onError,
|
||||
onUpdate,
|
||||
|
@ -17,7 +17,7 @@ export const EditFederatedSAMLApp = ({
|
|||
excludeFields,
|
||||
}: {
|
||||
urls: { getApp: string; updateApp: string; deleteApp: string };
|
||||
onUpdate?: (data: SAMLFederationApp) => void;
|
||||
onUpdate?: (data: IdentityFederationApp) => void;
|
||||
onError?: (error: Error) => void;
|
||||
onDelete?: () => void;
|
||||
excludeFields?: 'product'[];
|
||||
|
@ -25,7 +25,7 @@ export const EditFederatedSAMLApp = ({
|
|||
const { t } = useTranslation('common');
|
||||
const [delModalVisible, setDelModalVisible] = useState(false);
|
||||
|
||||
const { data, isLoading, error, mutate } = useSWR<{ data: SAMLFederationApp }>(urls.getApp, fetcher);
|
||||
const { data, isLoading, error, mutate } = useSWR<{ data: IdentityFederationApp }>(urls.getApp, fetcher);
|
||||
|
||||
useEffect(() => {
|
||||
if (error) {
|
|
@ -11,7 +11,7 @@ import {
|
|||
ButtonPrimary,
|
||||
} from '../shared';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import type { SAMLFederationApp } from '../types';
|
||||
import type { IdentityFederationApp } from '../types';
|
||||
import PencilIcon from '@heroicons/react/24/outline/PencilIcon';
|
||||
import { TableBodyType } from '../shared/Table';
|
||||
import { pageLimit } from '../shared/Pagination';
|
||||
|
@ -19,9 +19,9 @@ import { usePaginate } from '../hooks';
|
|||
import { useRouter } from '../hooks';
|
||||
import { useEffect } from 'react';
|
||||
|
||||
type ExcludeFields = keyof Pick<SAMLFederationApp, 'product'>;
|
||||
type ExcludeFields = keyof Pick<IdentityFederationApp, 'product'>;
|
||||
|
||||
export const FederatedSAMLApps = ({
|
||||
export const IdentityFederationApps = ({
|
||||
urls,
|
||||
excludeFields,
|
||||
onEdit,
|
||||
|
@ -30,9 +30,9 @@ export const FederatedSAMLApps = ({
|
|||
}: {
|
||||
urls: { getApps: string };
|
||||
excludeFields?: ExcludeFields[];
|
||||
onEdit?: (app: SAMLFederationApp) => void;
|
||||
onEdit?: (app: IdentityFederationApp) => void;
|
||||
actions: { newApp: string; samlConfiguration: string; oidcConfiguration: string };
|
||||
actionCols?: { text: string; onClick: (app: SAMLFederationApp) => void; icon: JSX.Element }[];
|
||||
actionCols?: { text: string; onClick: (app: IdentityFederationApp) => void; icon: JSX.Element }[];
|
||||
}) => {
|
||||
const { router } = useRouter();
|
||||
const { t } = useTranslation('common');
|
||||
|
@ -45,7 +45,7 @@ export const FederatedSAMLApps = ({
|
|||
getAppsUrl += `&pageToken=${pageTokenMap[paginate.offset - pageLimit]}`;
|
||||
}
|
||||
|
||||
const { data, isLoading, error } = useSWR<{ data: SAMLFederationApp[]; pageToken?: string }>(
|
||||
const { data, isLoading, error } = useSWR<{ data: IdentityFederationApp[]; pageToken?: string }>(
|
||||
getAppsUrl,
|
||||
fetcher
|
||||
);
|
|
@ -2,19 +2,19 @@ import { useFormik } from 'formik';
|
|||
import TagsInput from 'react-tagsinput';
|
||||
import { Card, Button } from 'react-daisyui';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import type { SAMLFederationApp } from '../types';
|
||||
import type { IdentityFederationApp } from '../types';
|
||||
import QuestionMarkCircleIcon from '@heroicons/react/24/outline/QuestionMarkCircleIcon';
|
||||
import { defaultHeaders } from '../utils';
|
||||
import { AttributesMapping } from './AttributesMapping';
|
||||
import { PageHeader } from '../shared';
|
||||
import { ItemList } from '@boxyhq/react-ui/shared';
|
||||
|
||||
type NewSAMLFederationApp = Pick<
|
||||
SAMLFederationApp,
|
||||
type NewIdentityFederationApp = Pick<
|
||||
IdentityFederationApp,
|
||||
'name' | 'tenant' | 'product' | 'acsUrl' | 'entityId' | 'tenants' | 'mappings' | 'type' | 'redirectUrl'
|
||||
>;
|
||||
|
||||
export const NewFederatedSAMLApp = ({
|
||||
export const NewIdentityFederationApp = ({
|
||||
samlAudience = 'https://saml.boxyhq.com',
|
||||
urls,
|
||||
onSuccess,
|
||||
|
@ -24,14 +24,14 @@ export const NewFederatedSAMLApp = ({
|
|||
}: {
|
||||
samlAudience?: string;
|
||||
urls: { createApp: string };
|
||||
onSuccess?: (data: SAMLFederationApp) => void;
|
||||
onSuccess?: (data: IdentityFederationApp) => void;
|
||||
onError?: (error: Error) => void;
|
||||
onEntityIdGenerated?: (entityId: string) => void;
|
||||
excludeFields?: 'product'[];
|
||||
}) => {
|
||||
const { t } = useTranslation('common');
|
||||
|
||||
const initialValues: NewSAMLFederationApp = {
|
||||
const initialValues: NewIdentityFederationApp = {
|
||||
type: 'saml',
|
||||
name: '',
|
||||
tenant: '',
|
||||
|
@ -44,11 +44,11 @@ export const NewFederatedSAMLApp = ({
|
|||
|
||||
if (excludeFields) {
|
||||
excludeFields.forEach((key) => {
|
||||
delete initialValues[key as keyof NewSAMLFederationApp];
|
||||
delete initialValues[key as keyof NewIdentityFederationApp];
|
||||
});
|
||||
}
|
||||
|
||||
const formik = useFormik<NewSAMLFederationApp>({
|
||||
const formik = useFormik<NewIdentityFederationApp>({
|
||||
initialValues: initialValues,
|
||||
onSubmit: async (values) => {
|
||||
const rawResponse = await fetch(urls.createApp, {
|
|
@ -0,0 +1,3 @@
|
|||
export { NewIdentityFederationApp as NewFederatedSAMLApp } from './NewIdentityFederationApp';
|
||||
export { EditIdentityFederationApp as EditFederatedSAMLApp } from './EditIdentityFederationApp';
|
||||
export { IdentityFederationApps as FederatedSAMLApps } from './IdentityFederationApps';
|
|
@ -1,7 +1,7 @@
|
|||
export * from './well-known';
|
||||
export * from './federated-saml';
|
||||
export * from './identity-federation';
|
||||
export * from './shared';
|
||||
export * from './dsync';
|
||||
export * from './provider';
|
||||
export * from './sso-tracer';
|
||||
export * from './sso-traces';
|
||||
export * from './setup-link';
|
||||
|
|
|
@ -10,7 +10,7 @@ import { addQueryParamsToPath, copyToClipboard, fetcher } from '../utils';
|
|||
import { TableBodyType } from '../shared/Table';
|
||||
import { pageLimit } from '../shared/Pagination';
|
||||
import { usePaginate, useRouter } from '../hooks';
|
||||
import type { SAMLFederationApp, SetupLink, SetupLinkService } from '../types';
|
||||
import type { IdentityFederationApp, SetupLink, SetupLinkService } from '../types';
|
||||
import {
|
||||
Loading,
|
||||
Table,
|
||||
|
@ -24,7 +24,7 @@ import {
|
|||
} from '../shared';
|
||||
import { SetupLinkInfoModal } from './SetupLinkInfoModal';
|
||||
|
||||
type ExcludeFields = keyof Pick<SAMLFederationApp, 'product'>;
|
||||
type ExcludeFields = keyof Pick<IdentityFederationApp, 'product'>;
|
||||
|
||||
export const SetupLinks = ({
|
||||
urls,
|
||||
|
|
|
@ -90,7 +90,7 @@ export type AttributeMapping = {
|
|||
value: string;
|
||||
};
|
||||
|
||||
export type SAMLFederationApp = {
|
||||
export type IdentityFederationApp = {
|
||||
id: string;
|
||||
type?: string;
|
||||
clientID?: string;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
{
|
||||
"apps": "Apps",
|
||||
"error_loading_page": "Unable to load this page. Maybe you don't have enough rights.",
|
||||
"documentation": "Documentation",
|
||||
"back": "Back",
|
||||
|
@ -41,7 +42,7 @@
|
|||
"directory_created_successfully": "Directory created successfully",
|
||||
"directory_updated_successfully": "Directory updated successfully",
|
||||
"dashboard": "Dashboard",
|
||||
"saml_federation": "Identity Federation",
|
||||
"identity_federation": "Identity Federation",
|
||||
"settings": "Settings",
|
||||
"admin_portal_sso": "SSO for Admin Portal",
|
||||
"configuration": "Configuration",
|
||||
|
@ -224,7 +225,7 @@
|
|||
"bui-dsync-authorization-google": "Authorize Google Workspace",
|
||||
"bui-dsync-authorization-google-desc": "You should authorize Google Workspace to sync your directory. Click the button below start the authorization process. Make sure you have the necessary permissions to authorize Google Workspace.",
|
||||
"bui-dsync-google-domain": "Google Domain",
|
||||
"bui-tracer-title": "SSO Tracer",
|
||||
"bui-tracer-title": "SSO Traces",
|
||||
"bui-tracer-id": "Trace ID",
|
||||
"bui-tracer-description": "Description",
|
||||
"bui-tracer-assertion-type": "Assertion Type",
|
||||
|
|
|
@ -11,6 +11,7 @@ const unAuthenticatedApiRoutes = [
|
|||
'/api/hello',
|
||||
'/api/auth/**',
|
||||
'/api/federated-saml/**',
|
||||
'/api/identity-federation/**',
|
||||
'/api/logout/**',
|
||||
'/api/oauth/**',
|
||||
'/api/scim/v2.0/**',
|
||||
|
|
|
@ -101,6 +101,10 @@ module.exports = {
|
|||
source: '/api/v1/saml-traces/:path*',
|
||||
destination: '/api/v1/sso-traces/:path*',
|
||||
},
|
||||
{
|
||||
source: '/api/v1/federated-saml/:path*',
|
||||
destination: '/api/v1/identity-federation/:path*',
|
||||
},
|
||||
];
|
||||
},
|
||||
images: {
|
||||
|
|
|
@ -26,8 +26,8 @@ const map = {
|
|||
'src/directory-sync/request.ts',
|
||||
],
|
||||
'test/dsync/events.test.ts': ['src/directory-sync/events.ts'],
|
||||
'test/federated-saml/app.test.ts': ['src/ee/federated-saml/app.ts'],
|
||||
'test/federated-saml/sso.test.ts': ['src/ee/federated-saml/sso.ts'],
|
||||
'test/identity-federation/app.test.ts': ['src/ee/identity-federation/app.ts'],
|
||||
'test/identity-federation/sso.test.ts': ['src/ee/identity-federation/sso.ts'],
|
||||
'test/event/index.test.ts': ['src/event/*'],
|
||||
'test/dsync/google_oauth.test.ts': [
|
||||
'src/directory-sync/non-scim/google/oauth.ts',
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -39,8 +39,8 @@
|
|||
"coverage-map": "map.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@aws-sdk/client-dynamodb": "3.565.0",
|
||||
"@aws-sdk/credential-providers": "3.565.0",
|
||||
"@aws-sdk/client-dynamodb": "3.567.0",
|
||||
"@aws-sdk/credential-providers": "3.567.0",
|
||||
"@aws-sdk/util-dynamodb": "3.565.0",
|
||||
"@boxyhq/error-code-mnemonic": "0.1.1",
|
||||
"@boxyhq/metrics": "0.2.6",
|
||||
|
@ -65,7 +65,7 @@
|
|||
"devDependencies": {
|
||||
"@faker-js/faker": "8.4.1",
|
||||
"@types/lodash": "4.17.0",
|
||||
"@types/node": "20.12.7",
|
||||
"@types/node": "20.12.8",
|
||||
"@types/sinon": "17.0.3",
|
||||
"@types/tap": "15.0.11",
|
||||
"cross-env": "7.0.3",
|
||||
|
|
|
@ -21,7 +21,7 @@ import type {
|
|||
SSOTracerInstance,
|
||||
OAuthErrorHandlerParams,
|
||||
OIDCAuthzResponsePayload,
|
||||
SAMLFederationApp,
|
||||
IdentityFederationApp,
|
||||
} from '../typings';
|
||||
import {
|
||||
relayStatePrefix,
|
||||
|
@ -45,7 +45,7 @@ import { getDefaultCertificate } from '../saml/x509';
|
|||
import { SSOHandler } from './sso-handler';
|
||||
import { ValidateOption, extractSAMLResponseAttributes } from '../saml/lib';
|
||||
import { oidcIssuerInstance } from './oauth/oidc-issuer';
|
||||
import { App } from '../ee/federated-saml/app';
|
||||
import { App } from '../ee/identity-federation/app';
|
||||
|
||||
const deflateRawAsync = promisify(deflateRaw);
|
||||
|
||||
|
@ -96,7 +96,7 @@ export class OAuthController implements IOAuthController {
|
|||
let requestedOIDCFlow: boolean | undefined;
|
||||
let isOIDCFederated: boolean | undefined;
|
||||
let connection: SAMLSSORecord | OIDCSSORecord | undefined;
|
||||
let fedApp: SAMLFederationApp | undefined;
|
||||
let fedApp: IdentityFederationApp | undefined;
|
||||
|
||||
try {
|
||||
const tenant = 'tenant' in body ? body.tenant : undefined;
|
||||
|
|
|
@ -5,7 +5,13 @@ import { deflateRaw } from 'zlib';
|
|||
import type { SAMLProfile } from '@boxyhq/saml20/dist/typings';
|
||||
import { generators } from 'openid-client';
|
||||
|
||||
import type { JacksonOption, Storable, SAMLSSORecord, OIDCSSORecord, SAMLFederationApp } from '../typings';
|
||||
import type {
|
||||
JacksonOption,
|
||||
Storable,
|
||||
SAMLSSORecord,
|
||||
OIDCSSORecord,
|
||||
IdentityFederationApp,
|
||||
} from '../typings';
|
||||
import { getDefaultCertificate } from '../saml/x509';
|
||||
import * as dbutils from '../db/utils';
|
||||
import { JacksonError } from './error';
|
||||
|
@ -167,7 +173,7 @@ export class SSOHandler {
|
|||
}: {
|
||||
connection: SAMLSSORecord;
|
||||
requestParams: Record<string, any>;
|
||||
mappings: SAMLFederationApp['mappings'];
|
||||
mappings: IdentityFederationApp['mappings'];
|
||||
}) {
|
||||
// We have a connection now, so we can create the SAML request
|
||||
const certificate = await getDefaultCertificate();
|
||||
|
@ -240,7 +246,7 @@ export class SSOHandler {
|
|||
}: {
|
||||
connection: OIDCSSORecord;
|
||||
requestParams: Record<string, any>;
|
||||
mappings: SAMLFederationApp['mappings'];
|
||||
mappings: IdentityFederationApp['mappings'];
|
||||
}) {
|
||||
if (!this.opts.oidcPath) {
|
||||
throw new JacksonError('OpenID response handler path (oidcPath) is not set', 400);
|
||||
|
@ -347,7 +353,7 @@ export class SSOHandler {
|
|||
requested: any;
|
||||
oidcCodeVerifier?: string;
|
||||
oidcNonce?: string;
|
||||
mappings: SAMLFederationApp['mappings'];
|
||||
mappings: IdentityFederationApp['mappings'];
|
||||
}) => {
|
||||
const sessionId = crypto.randomBytes(16).toString('hex');
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ import saml from '@boxyhq/saml20';
|
|||
import type {
|
||||
Storable,
|
||||
JacksonOption,
|
||||
SAMLFederationApp,
|
||||
IdentityFederationApp,
|
||||
Records,
|
||||
GetByProductParams,
|
||||
AppRequestParams,
|
||||
|
@ -17,7 +17,7 @@ import { IndexNames, validateTenantAndProduct } from '../../controller/utils';
|
|||
import { throwIfInvalidLicense } from '../common/checkLicense';
|
||||
|
||||
type NewAppParams = Pick<
|
||||
SAMLFederationApp,
|
||||
IdentityFederationApp,
|
||||
'name' | 'tenant' | 'product' | 'acsUrl' | 'entityId' | 'tenants' | 'mappings' | 'type' | 'redirectUrl'
|
||||
> & {
|
||||
logoUrl?: string;
|
||||
|
@ -32,7 +32,7 @@ export class App {
|
|||
/**
|
||||
* @swagger
|
||||
* definitions:
|
||||
* SAMLFederationApp:
|
||||
* IdentityFederationApp:
|
||||
* type: object
|
||||
* properties:
|
||||
* id:
|
||||
|
@ -71,7 +71,7 @@ export class App {
|
|||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/federated-saml:
|
||||
* /api/v1/identity-federation:
|
||||
* post:
|
||||
* summary: Create an Identity Federation app
|
||||
* parameters:
|
||||
|
@ -147,7 +147,7 @@ export class App {
|
|||
* schema:
|
||||
* type: array
|
||||
* items:
|
||||
* $ref: '#/definitions/SAMLFederationApp'
|
||||
* $ref: '#/definitions/IdentityFederationApp'
|
||||
*/
|
||||
public async create({
|
||||
name,
|
||||
|
@ -201,7 +201,7 @@ export class App {
|
|||
value: entityId,
|
||||
});
|
||||
|
||||
const apps: SAMLFederationApp[] = result.data;
|
||||
const apps: IdentityFederationApp[] = result.data;
|
||||
|
||||
if (apps && apps.length > 0) {
|
||||
throw new JacksonError(
|
||||
|
@ -219,7 +219,7 @@ export class App {
|
|||
_tenants.push(tenant);
|
||||
}
|
||||
|
||||
const app: SAMLFederationApp = {
|
||||
const app: IdentityFederationApp = {
|
||||
id,
|
||||
type,
|
||||
redirectUrl,
|
||||
|
@ -261,7 +261,7 @@ export class App {
|
|||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/federated-saml:
|
||||
* /api/v1/identity-federation:
|
||||
* get:
|
||||
* summary: Get an Identity Federation app
|
||||
* parameters:
|
||||
|
@ -288,7 +288,7 @@ export class App {
|
|||
* '200':
|
||||
* description: Success
|
||||
* schema:
|
||||
* $ref: '#/definitions/SAMLFederationApp'
|
||||
* $ref: '#/definitions/IdentityFederationApp'
|
||||
*/
|
||||
public async get(params: AppRequestParams) {
|
||||
await throwIfInvalidLicense(this.opts.boxyhqLicenseKey);
|
||||
|
@ -300,7 +300,7 @@ export class App {
|
|||
throw new JacksonError('Identity Federation app not found', 404);
|
||||
}
|
||||
|
||||
return app as SAMLFederationApp;
|
||||
return app as IdentityFederationApp;
|
||||
}
|
||||
|
||||
if ('tenant' in params && 'product' in params) {
|
||||
|
@ -310,7 +310,7 @@ export class App {
|
|||
throw new JacksonError('Identity Federation app not found', 404);
|
||||
}
|
||||
|
||||
return app as SAMLFederationApp;
|
||||
return app as IdentityFederationApp;
|
||||
}
|
||||
|
||||
throw new JacksonError('Provide either the `id` or `tenant` and `product` to get the app', 400);
|
||||
|
@ -318,7 +318,7 @@ export class App {
|
|||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/federated-saml/product:
|
||||
* /api/v1/identity-federation/product:
|
||||
* get:
|
||||
* summary: Get Identity Federation apps by product
|
||||
* parameters:
|
||||
|
@ -345,7 +345,7 @@ export class App {
|
|||
* data:
|
||||
* type: array
|
||||
* items:
|
||||
* $ref: '#/definitions/SAMLFederationApp'
|
||||
* $ref: '#/definitions/IdentityFederationApp'
|
||||
* pageToken:
|
||||
* type: string
|
||||
* description: token for pagination
|
||||
|
@ -378,7 +378,7 @@ export class App {
|
|||
throw new JacksonError('Missing required parameters. Required parameters are: entityId', 400);
|
||||
}
|
||||
|
||||
const apps: SAMLFederationApp[] = (
|
||||
const apps: IdentityFederationApp[] = (
|
||||
await this.store.getByIndex({
|
||||
name: IndexNames.EntityID,
|
||||
value: entityId,
|
||||
|
@ -394,7 +394,7 @@ export class App {
|
|||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/federated-saml:
|
||||
* /api/v1/identity-federation:
|
||||
* patch:
|
||||
* summary: Update an Identity Federation app
|
||||
* parameters:
|
||||
|
@ -459,9 +459,9 @@ export class App {
|
|||
* '200':
|
||||
* description: Success
|
||||
* schema:
|
||||
* $ref: '#/definitions/SAMLFederationApp'
|
||||
* $ref: '#/definitions/IdentityFederationApp'
|
||||
*/
|
||||
public async update(params: Partial<SAMLFederationApp>) {
|
||||
public async update(params: Partial<IdentityFederationApp>) {
|
||||
await throwIfInvalidLicense(this.opts.boxyhqLicenseKey);
|
||||
|
||||
const { id, tenant, product, type } = params;
|
||||
|
@ -470,7 +470,7 @@ export class App {
|
|||
throw new JacksonError('Provide either the `id` or `tenant` and `product` to update the app', 400);
|
||||
}
|
||||
|
||||
let app: null | SAMLFederationApp = null;
|
||||
let app: null | IdentityFederationApp = null;
|
||||
|
||||
if (id) {
|
||||
app = await this.get({ id });
|
||||
|
@ -482,7 +482,7 @@ export class App {
|
|||
throw new JacksonError('Identity Federation app not found', 404);
|
||||
}
|
||||
|
||||
const toUpdate: Partial<SAMLFederationApp> = {};
|
||||
const toUpdate: Partial<IdentityFederationApp> = {};
|
||||
|
||||
// Support partial updates
|
||||
|
||||
|
@ -556,14 +556,18 @@ export class App {
|
|||
}) {
|
||||
await throwIfInvalidLicense(this.opts.boxyhqLicenseKey);
|
||||
|
||||
const apps = (await this.store.getAll(pageOffset, pageLimit, pageToken)) as Records<SAMLFederationApp>;
|
||||
const apps = (await this.store.getAll(
|
||||
pageOffset,
|
||||
pageLimit,
|
||||
pageToken
|
||||
)) as Records<IdentityFederationApp>;
|
||||
|
||||
return apps;
|
||||
}
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/federated-saml:
|
||||
* /api/v1/identity-federation:
|
||||
* delete:
|
||||
* summary: Delete an Identity Federation app
|
||||
* parameters:
|
||||
|
@ -590,7 +594,7 @@ export class App {
|
|||
* '200':
|
||||
* description: Success
|
||||
* schema:
|
||||
* $ref: '#/definitions/SAMLFederationApp'
|
||||
* $ref: '#/definitions/IdentityFederationApp'
|
||||
*/
|
||||
public async delete(params: AppRequestParams): Promise<void> {
|
||||
await throwIfInvalidLicense(this.opts.boxyhqLicenseKey);
|
||||
|
@ -613,7 +617,7 @@ export class App {
|
|||
|
||||
const { publicKey } = await getDefaultCertificate();
|
||||
|
||||
const ssoUrl = `${this.opts.externalUrl}/api/federated-saml/sso`;
|
||||
const ssoUrl = `${this.opts.externalUrl}/api/identity-federation/sso`;
|
||||
const entityId = `${this.opts.samlAudience}`;
|
||||
|
||||
const xml = saml.createIdPMetadataXML({
|
|
@ -4,7 +4,7 @@ import type { JacksonOption, SSOTracerInstance } from '../../typings';
|
|||
import { SSOHandler } from '../../controller/sso-handler';
|
||||
|
||||
// This is the main entry point for the Identity Federation module
|
||||
const SAMLFederation = async ({
|
||||
const IdentityFederation = async ({
|
||||
db,
|
||||
opts,
|
||||
ssoTracer,
|
||||
|
@ -34,7 +34,7 @@ const SAMLFederation = async ({
|
|||
return response;
|
||||
};
|
||||
|
||||
export default SAMLFederation;
|
||||
export default IdentityFederation;
|
||||
|
||||
export * from './types';
|
||||
|
|
@ -6,7 +6,7 @@ import { SSOHandler } from '../../controller/sso-handler';
|
|||
import type {
|
||||
JacksonOption,
|
||||
OIDCSSORecord,
|
||||
SAMLFederationApp,
|
||||
IdentityFederationApp,
|
||||
SAMLSSORecord,
|
||||
SSOTracerInstance,
|
||||
} from '../../typings';
|
||||
|
@ -56,7 +56,7 @@ export class SSO {
|
|||
|
||||
const isPostBinding = samlBinding === 'HTTP-POST';
|
||||
let connection: SAMLSSORecord | OIDCSSORecord | undefined;
|
||||
let app: SAMLFederationApp | undefined;
|
||||
let app: IdentityFederationApp | undefined;
|
||||
let id, acsUrl, entityId, publicKey, providerName, decodedRequest;
|
||||
|
||||
try {
|
|
@ -1,13 +1,13 @@
|
|||
import SAMLFederation from '.';
|
||||
import IdentityFederation from '.';
|
||||
|
||||
export type ISAMLFederationController = Awaited<ReturnType<typeof SAMLFederation>>;
|
||||
export type IIdentityFederationController = Awaited<ReturnType<typeof IdentityFederation>>;
|
||||
|
||||
export type AttributeMapping = {
|
||||
key: string;
|
||||
value: string;
|
||||
};
|
||||
|
||||
export type SAMLFederationApp = {
|
||||
export type IdentityFederationApp = {
|
||||
id: string;
|
||||
type?: string;
|
||||
clientID?: string;
|
||||
|
@ -25,7 +25,7 @@ export type SAMLFederationApp = {
|
|||
mappings?: AttributeMapping[] | null;
|
||||
};
|
||||
|
||||
export type SAMLFederationAppWithMetadata = SAMLFederationApp & {
|
||||
export type IdentityFederationAppWithMetadata = IdentityFederationApp & {
|
||||
metadata: {
|
||||
entityId: string;
|
||||
ssoUrl: string;
|
|
@ -13,10 +13,10 @@ import { SPSSOConfig } from './controller/sp-config';
|
|||
import { SetupLinkController } from './controller/setup-link';
|
||||
import { AnalyticsController } from './controller/analytics';
|
||||
import * as x509 from './saml/x509';
|
||||
import initFederatedSAML, { type ISAMLFederationController } from './ee/federated-saml';
|
||||
import initFederatedSAML, { type IIdentityFederationController } from './ee/identity-federation';
|
||||
import checkLicense from './ee/common/checkLicense';
|
||||
import { BrandingController } from './ee/branding';
|
||||
import SSOTracer from './sso-tracer';
|
||||
import SSOTracer from './sso-traces';
|
||||
import EventController from './event';
|
||||
import { ProductController } from './ee/product';
|
||||
import { OryController } from './ee/ory/ory';
|
||||
|
@ -71,7 +71,7 @@ export const controllers = async (
|
|||
directorySyncController: IDirectorySyncController;
|
||||
oidcDiscoveryController: OidcDiscoveryController;
|
||||
spConfig: SPSSOConfig;
|
||||
samlFederatedController: ISAMLFederationController;
|
||||
samlFederatedController: IIdentityFederationController;
|
||||
brandingController: IBrandingController;
|
||||
checkLicense: () => Promise<boolean>;
|
||||
productController: ProductController;
|
||||
|
@ -194,7 +194,7 @@ export const controllers = async (
|
|||
export default controllers;
|
||||
|
||||
export * from './typings';
|
||||
export * from './ee/federated-saml/types';
|
||||
export * from './ee/identity-federation/types';
|
||||
export type SAMLJackson = Awaited<ReturnType<typeof controllers>>;
|
||||
export type ISetupLinkController = InstanceType<typeof SetupLinkController>;
|
||||
export type IBrandingController = InstanceType<typeof BrandingController>;
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import type { JWK } from 'jose';
|
||||
import type { CallbackParamsType, IssuerMetadata } from 'openid-client';
|
||||
|
||||
export * from './ee/federated-saml/types';
|
||||
export * from './sso-tracer/types';
|
||||
export * from './ee/identity-federation/types';
|
||||
export * from './sso-traces/types';
|
||||
export * from './directory-sync/types';
|
||||
export * from './event/types';
|
||||
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
<samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="ONELOGIN_082f89d9-a32a-441d-ae49-ab6fc13fe73b" Version="2.0" IssueInstant="2022-11-29T09:04:48Z" ProviderName="Twilio" Destination="http://localhost:5225/api/federated-saml/sso" ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" AssertionConsumerServiceURL="https://twilio.com/saml2/acs"><saml:Issuer>https://twilio.com/saml2/entityId</saml:Issuer><samlp:NameIDPolicy Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress" AllowCreate="true" /><samlp:RequestedAuthnContext Comparison="exact"><saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml:AuthnContextClassRef></samlp:RequestedAuthnContext></samlp:AuthnRequest>
|
|
@ -1,11 +1,11 @@
|
|||
import tap from 'tap';
|
||||
|
||||
import { ISAMLFederationController } from '../../src';
|
||||
import { IIdentityFederationController } from '../../src';
|
||||
import { jacksonOptions } from '../utils';
|
||||
import { tenant, product, serviceProvider, appId } from './constants';
|
||||
import { getDefaultCertificate } from '../../src/saml/x509';
|
||||
|
||||
let samlFederatedController: ISAMLFederationController;
|
||||
let samlFederatedController: IIdentityFederationController;
|
||||
|
||||
tap.before(async () => {
|
||||
const jackson = await (await import('../../src/index')).default(jacksonOptions);
|
||||
|
@ -149,7 +149,7 @@ tap.test('Federated SAML App', async () => {
|
|||
|
||||
t.ok(response);
|
||||
t.match(response.entityId, jacksonOptions.samlAudience);
|
||||
t.match(response.ssoUrl, `${jacksonOptions.externalUrl}/api/federated-saml/sso`);
|
||||
t.match(response.ssoUrl, `${jacksonOptions.externalUrl}/api/identity-federation/sso`);
|
||||
t.match(response.x509cert, certs.publicKey);
|
||||
});
|
||||
|
|
@ -0,0 +1 @@
|
|||
<samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="ONELOGIN_082f89d9-a32a-441d-ae49-ab6fc13fe73b" Version="2.0" IssueInstant="2022-11-29T09:04:48Z" ProviderName="Twilio" Destination="http://localhost:5225/api/identity-federation/sso" ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" AssertionConsumerServiceURL="https://twilio.com/saml2/acs"><saml:Issuer>https://twilio.com/saml2/entityId</saml:Issuer><samlp:NameIDPolicy Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress" AllowCreate="true" /><samlp:RequestedAuthnContext Comparison="exact"><saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml:AuthnContextClassRef></samlp:RequestedAuthnContext></samlp:AuthnRequest>
|
|
@ -11,18 +11,18 @@ const deflateRawAsync = promisify(deflateRaw);
|
|||
import { jacksonOptions } from '../utils';
|
||||
import { tenant, product, serviceProvider } from './constants';
|
||||
import type {
|
||||
ISAMLFederationController,
|
||||
IIdentityFederationController,
|
||||
IConnectionAPIController,
|
||||
IOAuthController,
|
||||
SAMLFederationApp,
|
||||
IdentityFederationApp,
|
||||
SAMLSSORecord,
|
||||
} from '../../src';
|
||||
|
||||
let oauthController: IOAuthController;
|
||||
let samlFederatedController: ISAMLFederationController;
|
||||
let samlFederatedController: IIdentityFederationController;
|
||||
let connectionAPIController: IConnectionAPIController;
|
||||
|
||||
let app: SAMLFederationApp;
|
||||
let app: IdentityFederationApp;
|
||||
let connection: SAMLSSORecord;
|
||||
|
||||
tap.before(async () => {
|
|
@ -1,5 +1,5 @@
|
|||
import tap from 'tap';
|
||||
import SSOTracer from '../../src/sso-tracer';
|
||||
import SSOTracer from '../../src/sso-traces';
|
||||
import { jacksonOptions } from '../utils';
|
||||
import DB from '../../src/db/db';
|
||||
|
|
@ -24,7 +24,7 @@
|
|||
"classnames": "2.5.1",
|
||||
"cors": "2.8.5",
|
||||
"cross-env": "7.0.3",
|
||||
"daisyui": "4.10.2",
|
||||
"daisyui": "4.10.3",
|
||||
"formik": "2.4.6",
|
||||
"i18next": "23.11.3",
|
||||
"medium-zoom": "1.1.0",
|
||||
|
@ -97,7 +97,7 @@
|
|||
"vite": "5.2.10"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@rollup/rollup-linux-x64-gnu": "4.17.1"
|
||||
"@rollup/rollup-linux-x64-gnu": "4.17.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@boxyhq/react-ui": ">=3.3.42",
|
||||
|
@ -4311,9 +4311,9 @@
|
|||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-x64-gnu": {
|
||||
"version": "4.17.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.17.1.tgz",
|
||||
"integrity": "sha512-AsdnINQoDWfKpBzCPqQWxSPdAWzSgnYbrJYtn6W0H2E9It5bZss99PiLA8CgmDRfvKygt20UpZ3xkhFlIfX9zQ==",
|
||||
"version": "4.17.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.17.2.tgz",
|
||||
"integrity": "sha512-Hy7pLwByUOuyaFC6mAr7m+oMC+V7qyifzs/nW2OJfC8H4hbCzOX07Ov0VFk/zP3kBsELWNFi7rJtgbKYsav9QQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
@ -8108,9 +8108,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/daisyui": {
|
||||
"version": "4.10.2",
|
||||
"resolved": "https://registry.npmjs.org/daisyui/-/daisyui-4.10.2.tgz",
|
||||
"integrity": "sha512-eCWS1W/JPyxW9IvlgW5m0R6rp9ZhRsBTW37rvEUthckkjsV04u8XipV519OoccSA46ixhSJa3q7XLI1WUFtRCA==",
|
||||
"version": "4.10.3",
|
||||
"resolved": "https://registry.npmjs.org/daisyui/-/daisyui-4.10.3.tgz",
|
||||
"integrity": "sha512-LuxUmktsfO8nk0MKbg8NAth0K199pL2FzPMqhy7PGKFQ9LWIDdYVnc4f60Ior1bvbyZcXoH6/hhU068UuHksjA==",
|
||||
"dependencies": {
|
||||
"css-selector-tokenizer": "^0.8",
|
||||
"culori": "^3",
|
||||
|
|
|
@ -75,7 +75,7 @@
|
|||
"classnames": "2.5.1",
|
||||
"cors": "2.8.5",
|
||||
"cross-env": "7.0.3",
|
||||
"daisyui": "4.10.2",
|
||||
"daisyui": "4.10.3",
|
||||
"formik": "2.4.6",
|
||||
"i18next": "23.11.3",
|
||||
"medium-zoom": "1.1.0",
|
||||
|
|
|
@ -2,7 +2,7 @@ import { serverSideTranslations } from 'next-i18next/serverSideTranslations';
|
|||
|
||||
import jackson from '@lib/jackson';
|
||||
|
||||
export { default } from 'ee/federated-saml/pages/edit';
|
||||
export { default } from '@ee/identity-federation/pages/edit';
|
||||
|
||||
export async function getServerSideProps({ locale }) {
|
||||
const { checkLicense } = await jackson();
|
|
@ -2,7 +2,7 @@ import { serverSideTranslations } from 'next-i18next/serverSideTranslations';
|
|||
|
||||
import jackson from '@lib/jackson';
|
||||
|
||||
export { default } from 'ee/federated-saml/pages/index';
|
||||
export { default } from '@ee/identity-federation/pages/index';
|
||||
|
||||
export async function getServerSideProps({ locale }) {
|
||||
const { checkLicense } = await jackson();
|
|
@ -3,7 +3,7 @@ import { serverSideTranslations } from 'next-i18next/serverSideTranslations';
|
|||
import jackson from '@lib/jackson';
|
||||
import { jacksonOptions } from '@lib/env';
|
||||
|
||||
export { default } from 'ee/federated-saml/pages/new';
|
||||
export { default } from '@ee/identity-federation/pages/new';
|
||||
|
||||
export async function getServerSideProps({ locale }) {
|
||||
const { checkLicense } = await jackson();
|
|
@ -10,8 +10,8 @@ const SSOTraceInspector: NextPage = () => {
|
|||
|
||||
return (
|
||||
<div className='space-y-4'>
|
||||
<LinkBack href='/admin/sso-tracer' />
|
||||
<SSOTracerInfo urls={{ getTracer: `/api/admin/sso-tracer/${traceId}` }} />
|
||||
<LinkBack href='/admin/sso-traces' />
|
||||
<SSOTracerInfo urls={{ getTracer: `/api/admin/sso-traces/${traceId}` }} />
|
||||
</div>
|
||||
);
|
||||
};
|
|
@ -8,8 +8,8 @@ const SSOTraceViewer: NextPage = () => {
|
|||
|
||||
return (
|
||||
<SSOTracers
|
||||
urls={{ getTracers: '/api/admin/sso-tracer' }}
|
||||
onView={(trace) => router.push(`/admin/sso-tracer/${trace.traceId}/inspect`)}
|
||||
urls={{ getTracers: '/api/admin/sso-traces' }}
|
||||
onView={(trace) => router.push(`/admin/sso-traces/${trace.traceId}/inspect`)}
|
||||
/>
|
||||
);
|
||||
};
|
|
@ -1 +0,0 @@
|
|||
export { default } from 'ee/federated-saml/api/admin/[id]/index';
|
|
@ -1 +0,0 @@
|
|||
export { default } from 'ee/federated-saml/api/admin/index';
|
|
@ -0,0 +1 @@
|
|||
export { default } from '@ee/identity-federation/api/admin/[id]/index';
|
|
@ -0,0 +1 @@
|
|||
export { default } from '@ee/identity-federation/api/admin/index';
|
|
@ -1 +1 @@
|
|||
export { default } from 'ee/federated-saml/api/sso';
|
||||
export { default } from '@ee/identity-federation/api/sso';
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
export { default } from '@ee/identity-federation/api/sso';
|
|
@ -1 +0,0 @@
|
|||
export { default } from 'ee/federated-saml/api/v1/index';
|
|
@ -1 +0,0 @@
|
|||
export { default } from 'ee/federated-saml/api/v1/product';
|
|
@ -0,0 +1 @@
|
|||
export { default } from '@ee/identity-federation/api/v1/index';
|
|
@ -0,0 +1 @@
|
|||
export { default } from '@ee/identity-federation/api/v1/product';
|
|
@ -1 +1 @@
|
|||
export { default } from 'ee/federated-saml/api/metadata';
|
||||
export { default } from '@ee/identity-federation/api/metadata';
|
||||
|
|
|
@ -203,7 +203,7 @@ export const getServerSideProps = async ({ query, locale, req }) => {
|
|||
const params = new URLSearchParams(paramsToRelay);
|
||||
const destination =
|
||||
samlFedAppId && fedType !== 'oidc'
|
||||
? `/api/federated-saml/sso?${params}`
|
||||
? `/api/identity-federation/sso?${params}`
|
||||
: `/api/oauth/authorize?${params}`;
|
||||
|
||||
return {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { serverSideTranslations } from 'next-i18next/serverSideTranslations';
|
||||
import jackson from '@lib/jackson';
|
||||
|
||||
export { default } from 'ee/federated-saml/pages/metadata';
|
||||
export { default } from '@ee/identity-federation/pages/metadata';
|
||||
|
||||
export async function getServerSideProps({ locale }) {
|
||||
const { samlFederatedController, checkLicense } = await jackson();
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"openapi": "3.0.3",
|
||||
"info": {
|
||||
"title": "Enterprise SSO & Directory Sync",
|
||||
"version": "1.20.6",
|
||||
"version": "1.23.5",
|
||||
"description": "This is the API documentation for SAML Jackson service.",
|
||||
"termsOfService": "https://boxyhq.com/terms.html",
|
||||
"contact": {
|
||||
|
@ -1354,7 +1354,7 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/federated-saml": {
|
||||
"/api/v1/identity-federation": {
|
||||
"post": {
|
||||
"summary": "Create an Identity Federation app",
|
||||
"parameters": [
|
||||
|
@ -1459,7 +1459,7 @@
|
|||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/SAMLFederationApp"
|
||||
"$ref": "#/definitions/IdentityFederationApp"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1500,7 +1500,7 @@
|
|||
"200": {
|
||||
"description": "Success",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/SAMLFederationApp"
|
||||
"$ref": "#/definitions/IdentityFederationApp"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1593,7 +1593,7 @@
|
|||
"200": {
|
||||
"description": "Success",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/SAMLFederationApp"
|
||||
"$ref": "#/definitions/IdentityFederationApp"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1633,13 +1633,13 @@
|
|||
"200": {
|
||||
"description": "Success",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/SAMLFederationApp"
|
||||
"$ref": "#/definitions/IdentityFederationApp"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/federated-saml/product": {
|
||||
"/api/v1/identity-federation/product": {
|
||||
"get": {
|
||||
"summary": "Get Identity Federation apps by product",
|
||||
"parameters": [
|
||||
|
@ -1677,7 +1677,7 @@
|
|||
"data": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/SAMLFederationApp"
|
||||
"$ref": "#/definitions/IdentityFederationApp"
|
||||
}
|
||||
},
|
||||
"pageToken": {
|
||||
|
@ -2034,7 +2034,7 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"SAMLFederationApp": {
|
||||
"IdentityFederationApp": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
|
|
Loading…
Reference in New Issue