From cd0d3577ee331e4e104bb2162baf325b1cf89d49 Mon Sep 17 00:00:00 2001 From: Darcy Ye Date: Wed, 4 Dec 2024 23:27:34 -0800 Subject: [PATCH] refactor: remove SAML app certificate/metadata download APIs (#6856) --- .../src/saml-applications/routes/index.ts | 69 ------------------- .../core/src/utils/content-disposition.ts | 10 --- .../src/api/saml-application.ts | 3 - .../api/application/saml-application.test.ts | 8 +-- 4 files changed, 2 insertions(+), 88 deletions(-) delete mode 100644 packages/core/src/utils/content-disposition.ts diff --git a/packages/core/src/saml-applications/routes/index.ts b/packages/core/src/saml-applications/routes/index.ts index e78d4fe91..f3ee429b2 100644 --- a/packages/core/src/saml-applications/routes/index.ts +++ b/packages/core/src/saml-applications/routes/index.ts @@ -16,7 +16,6 @@ import { buildOidcClientMetadata } from '#src/oidc/utils.js'; import { generateInternalSecret } from '#src/routes/applications/application-secret.js'; import type { ManagementApiRouter, RouterInitArgs } from '#src/routes/types.js'; import assertThat from '#src/utils/assert-that.js'; -import { createContentDisposition } from '#src/utils/content-disposition.js'; import { calculateCertificateFingerprints, @@ -35,7 +34,6 @@ export default function samlApplicationRoutes( findSamlApplicationSecretsByApplicationId, findSamlApplicationSecretByApplicationIdAndId, updateSamlApplicationSecretStatusByApplicationIdAndSecretId, - findActiveSamlApplicationSecretByApplicationId, }, } = queries; const { @@ -43,7 +41,6 @@ export default function samlApplicationRoutes( createSamlApplicationSecret, findSamlApplicationById, updateSamlApplicationById, - getSamlIdPMetadataByApplicationId, }, } = libraries; @@ -270,70 +267,4 @@ export default function samlApplicationRoutes( return next(); } ); - - router.get( - '/saml-applications/:id/certificate', - koaGuard({ - params: z.object({ id: z.string() }), - status: [200, 400, 404], - response: samlApplicationSecretResponseGuard.pick({ - certificate: true, - fingerprints: true, - }), - }), - async (ctx, next) => { - const { id } = ctx.guard.params; - - const { certificate } = await findActiveSamlApplicationSecretByApplicationId(id); - - const fingerprints = calculateCertificateFingerprints(certificate); - - ctx.status = 200; - ctx.body = { certificate, fingerprints }; - - return next(); - } - ); - - router.get( - '/saml-applications/:id/certificate.pem', - koaGuard({ - params: z.object({ id: z.string() }), - status: [200, 400, 404], - response: z.string(), - }), - async (ctx, next) => { - const { id } = ctx.guard.params; - - const { certificate } = await findActiveSamlApplicationSecretByApplicationId(id); - - ctx.status = 200; - ctx.body = certificate; - ctx.type = 'application/x-pem-file'; - ctx.set('Content-Disposition', createContentDisposition(`certificate.pem`)); - - return next(); - } - ); - - router.get( - '/saml-applications/:id/metadata.xml', - koaGuard({ - params: z.object({ id: z.string() }), - status: [200, 404], - response: z.string(), - }), - async (ctx, next) => { - const { id } = ctx.guard.params; - - const { metadata } = await getSamlIdPMetadataByApplicationId(id); - - ctx.status = 200; - ctx.body = metadata; - ctx.type = 'text/xml;charset=utf-8'; - ctx.set('Content-Disposition', createContentDisposition(`metadata.xml`)); - - return next(); - } - ); } diff --git a/packages/core/src/utils/content-disposition.ts b/packages/core/src/utils/content-disposition.ts deleted file mode 100644 index f0a4c30a4..000000000 --- a/packages/core/src/utils/content-disposition.ts +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Generate Content-Disposition header value for file download - * @param filename The name of the file to be downloaded - * @returns Content-Disposition header value - */ -export const createContentDisposition = (filename: string) => { - // RFC 6266 requires the filename to be quoted and UTF-8 encoded - const encodedFilename = encodeURIComponent(filename); - return `attachment; filename="${encodedFilename}"; filename*=UTF-8''${encodedFilename}`; -}; diff --git a/packages/integration-tests/src/api/saml-application.ts b/packages/integration-tests/src/api/saml-application.ts index 95d4dd460..53015a5ba 100644 --- a/packages/integration-tests/src/api/saml-application.ts +++ b/packages/integration-tests/src/api/saml-application.ts @@ -44,9 +44,6 @@ export const updateSamlApplicationSecret = async (id: string, secretId: string, .patch(`saml-applications/${id}/secrets/${secretId}`, { json: { active } }) .json(); -export const getSamlApplicationCertificate = async (id: string) => - authedAdminApi.get(`saml-applications/${id}/certificate`).json<{ certificate: string }>(); - // Anonymous endpoints export const getSamlApplicationMetadata = async (id: string) => api diff --git a/packages/integration-tests/src/tests/api/application/saml-application.test.ts b/packages/integration-tests/src/tests/api/application/saml-application.test.ts index 6adcae11b..d1f8c565b 100644 --- a/packages/integration-tests/src/tests/api/application/saml-application.test.ts +++ b/packages/integration-tests/src/tests/api/application/saml-application.test.ts @@ -11,7 +11,6 @@ import { updateSamlApplicationSecret, getSamlApplicationSecrets, getSamlApplicationMetadata, - getSamlApplicationCertificate, } from '#src/api/saml-application.js'; import { expectRejects } from '#src/helpers/index.js'; import { devFeatureTest } from '#src/utils.js'; @@ -141,13 +140,12 @@ describe('SAML application secrets/certificate/metadata', () => { await deleteSamlApplication(id); }); - it('should be able to get certificate/metadata after creating a SAML app', async () => { + it('should be able to get metadata after creating a SAML app', async () => { const { id } = await createSamlApplication({ name: 'test', description: 'test', }); - await expect(getSamlApplicationCertificate(id)).resolves.not.toThrow(); await expect(getSamlApplicationMetadata(id)).resolves.not.toThrow(); await deleteSamlApplication(id); @@ -163,15 +161,13 @@ describe('SAML application secrets/certificate/metadata', () => { const updatedSecret = await updateSamlApplicationSecret(id, createdSecret.id, true); expect(updatedSecret.active).toBe(true); + expect(typeof updatedSecret.certificate).toBe('string'); const secrets = await getSamlApplicationSecrets(id); expect(secrets.length).toBe(2); expect(secrets.every(({ createdAt, expiresAt }) => createdAt < expiresAt)).toBe(true); expect(secrets.filter(({ active }) => active).length).toBe(1); - const { certificate } = await getSamlApplicationCertificate(id); - expect(typeof certificate).toBe('string'); - await deleteSamlApplication(id); });