diff --git a/e2e/smoke/test/saml.spec.ts b/e2e/smoke/test/saml.spec.ts index 78b6c80225..b05dbf2010 100644 --- a/e2e/smoke/test/saml.spec.ts +++ b/e2e/smoke/test/saml.spec.ts @@ -1,12 +1,10 @@ import assert from "node:assert/strict"; -import { createRequire } from "node:module"; import { DatabaseSync } from "node:sqlite"; import { describe, test } from "node:test"; +import { sso } from "@better-auth/sso"; import { betterAuth } from "better-auth"; import { getMigrations } from "better-auth/db/migration"; -const { sso } = createRequire(import.meta.url)("@better-auth/sso"); - const TEST_CERT = `MIIDXTCCAkWgAwIBAgIJAOxEm08dOr3PMA0GCSqGSIb3DqEBCwUAMEUxCzAJBgNV BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX aWRnaXRzIFB0eSBMdGQwHhcNMjMwMTAxMDAwMDAwWhcNMjQwMTAxMDAwMDAwWjBF @@ -29,6 +27,21 @@ r1PAFY+X3xF+5qDTbPpcHFPTIEWLpJFJPkSS+Q==`; const IDP_ENTRY_POINT = "https://idp.example.com/saml2/sso"; describe("SAML SSO", () => { + /** + * @see https://github.com/better-auth/better-auth/issues/8695 + * + * samlify is a CJS module with __esModule: true but no exports.default. + * Using `import saml from "samlify"` resolves to undefined in ESM, + * causing `saml.setSchemaValidator(...)` to throw at module load time. + * This test verifies that @better-auth/sso loads without error under ESM + * by using a native ESM import (not createRequire). + */ + test("should load @better-auth/sso via ESM without samlify import error", async () => { + const mod = await import("@better-auth/sso"); + assert.ok(mod.sso, "sso export should be defined"); + assert.equal(typeof mod.sso, "function", "sso should be a function"); + }); + test("should generate SAML login request URL via defaultSSO", async () => { const database = new DatabaseSync(":memory:"); const auth = betterAuth({ diff --git a/packages/sso/src/index.ts b/packages/sso/src/index.ts index 8e91a2768e..c55d84a89b 100644 --- a/packages/sso/src/index.ts +++ b/packages/sso/src/index.ts @@ -1,7 +1,7 @@ import type { BetterAuthPlugin } from "better-auth"; import { createAuthMiddleware, getSessionFromCtx } from "better-auth/api"; import { XMLValidator } from "fast-xml-parser"; -import saml from "samlify"; +import * as saml from "samlify"; import { SAML_SESSION_BY_ID_PREFIX } from "./constants"; import { assignOrganizationByDomain } from "./linking"; import { diff --git a/packages/sso/src/routes/helpers.ts b/packages/sso/src/routes/helpers.ts index 1a9cefca5f..ff9f18d10e 100644 --- a/packages/sso/src/routes/helpers.ts +++ b/packages/sso/src/routes/helpers.ts @@ -1,5 +1,5 @@ import type { DBAdapter } from "@better-auth/core/db/adapter"; -import saml from "samlify"; +import * as saml from "samlify"; import type { SAMLConfig, SSOOptions, SSOProvider } from "../types"; import { safeJsonParse } from "../utils"; diff --git a/packages/sso/src/routes/sso.ts b/packages/sso/src/routes/sso.ts index bad821fd56..4c53a7879d 100644 --- a/packages/sso/src/routes/sso.ts +++ b/packages/sso/src/routes/sso.ts @@ -19,7 +19,7 @@ import { generateRandomString } from "better-auth/crypto"; import { handleOAuthUserInfo } from "better-auth/oauth2"; import { XMLParser } from "fast-xml-parser"; import { decodeJwt } from "jose"; -import saml from "samlify"; +import * as saml from "samlify"; import type { BindingContext } from "samlify/types/src/entity"; import type { IdentityProvider } from "samlify/types/src/entity-idp"; import type { FlowResult } from "samlify/types/src/flow";