From a5a176a9376bd0de3a2a5c24b46c970b0ebbf4fa Mon Sep 17 00:00:00 2001 From: Brendan Kellam Date: Wed, 9 Sep 2026 16:21:45 -0700 Subject: [PATCH 1/2] fix(web): preserve Idira issuer trailing slash --- packages/web/src/ee/features/sso/sso.test.ts | 65 ++++++++++++++++++++ packages/web/src/ee/features/sso/sso.ts | 2 +- 2 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 packages/web/src/ee/features/sso/sso.test.ts diff --git a/packages/web/src/ee/features/sso/sso.test.ts b/packages/web/src/ee/features/sso/sso.test.ts new file mode 100644 index 000000000..81fc958e7 --- /dev/null +++ b/packages/web/src/ee/features/sso/sso.test.ts @@ -0,0 +1,65 @@ +import { beforeEach, describe, expect, test, vi } from 'vitest'; + +const mocks = vi.hoisted(() => ({ + getIdentityProviderConfigs: vi.fn(), + getTokenFromConfig: vi.fn(), +})); + +vi.mock('@/prisma', () => ({ + __unsafePrisma: {}, +})); +vi.mock('@/lib/entitlements', () => ({ + hasEntitlement: vi.fn(), +})); +vi.mock('@/features/membership/onCreateUser', () => ({ + onCreateUser: vi.fn(), +})); +vi.mock('@sourcebot/shared', () => ({ + createLogger: () => ({ warn: vi.fn() }), + env: { AUTH_EE_ALLOW_EMAIL_ACCOUNT_LINKING: 'false' }, + getIdentityProviderConfigs: mocks.getIdentityProviderConfigs, + getTokenFromConfig: mocks.getTokenFromConfig, +})); + +const { getEEIdentityProviders } = await import('./sso'); + +beforeEach(() => { + vi.clearAllMocks(); +}); + +describe('getEEIdentityProviders', () => { + test('preserves the configured Idira issuer trailing slash', async () => { + const clientId = { env: 'IDIRA_CLIENT_ID' }; + const clientSecret = { env: 'IDIRA_CLIENT_SECRET' }; + const issuerConfig = { env: 'IDIRA_ISSUER' }; + const issuer = 'https://example.id.cyberark.cloud/sourcebot/'; + + mocks.getIdentityProviderConfigs.mockResolvedValue({ + idira: { + provider: 'idira', + purpose: 'sso', + clientId, + clientSecret, + issuer: issuerConfig, + }, + }); + mocks.getTokenFromConfig.mockImplementation(async (token) => { + if (token === clientId) { + return 'client-id'; + } + if (token === clientSecret) { + return 'client-secret'; + } + if (token === issuerConfig) { + return issuer; + } + throw new Error('Unexpected token config'); + }); + + const providers = await getEEIdentityProviders(); + + expect(providers).toHaveLength(1); + expect(providers[0].issuerUrl).toBe(issuer); + expect(providers[0].__provider).toMatchObject({ issuer }); + }); +}); diff --git a/packages/web/src/ee/features/sso/sso.ts b/packages/web/src/ee/features/sso/sso.ts index 84e06a68a..412fe0f28 100644 --- a/packages/web/src/ee/features/sso/sso.ts +++ b/packages/web/src/ee/features/sso/sso.ts @@ -165,7 +165,7 @@ export const getEEIdentityProviders = async (): Promise => { if (idpConfig.provider === "idira") { const clientId = await getTokenFromConfig(idpConfig.clientId); const clientSecret = await getTokenFromConfig(idpConfig.clientSecret); - const issuer = (await getTokenFromConfig(idpConfig.issuer)).replace(/\/+$/, ''); + const issuer = await getTokenFromConfig(idpConfig.issuer); providers.push({ __provider: createIdiraProvider({ id, From 93a6c9585dd918c8989feeae0e2c8b3728de7c76 Mon Sep 17 00:00:00 2001 From: Brendan Kellam Date: Wed, 9 Sep 2026 16:22:30 -0700 Subject: [PATCH 2/2] docs: add Idira issuer fix changelog entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 845d9846b..c90c3850f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Upgraded `js-yaml` to `4.3.2`. [#1636](https://github.com/sourcebot-dev/sourcebot/pull/1636) - Upgraded `@humanfs/node` to `0.16.8`. [#1630](https://github.com/sourcebot-dev/sourcebot/pull/1630) - Upgraded `fflate` to `0.4.9`. [#1629](https://github.com/sourcebot-dev/sourcebot/pull/1629) +- [EE] Fixed Idira authentication for issuer URLs with a trailing slash. [#1641](https://github.com/sourcebot-dev/sourcebot/pull/1641) ## [5.1.10] - 2026-08-27