@better-auth/sso 1.4.6-beta.2 → 1.4.6-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,16 +1,16 @@
1
1
 
2
- > @better-auth/sso@1.4.6-beta.2 build /home/runner/work/better-auth/better-auth/packages/sso
2
+ > @better-auth/sso@1.4.6-beta.3 build /home/runner/work/better-auth/better-auth/packages/sso
3
3
  > tsdown
4
4
 
5
- ℹ tsdown v0.16.6 powered by rolldown v1.0.0-beta.51
6
- ℹ Using tsdown config: /home/runner/work/better-auth/better-auth/packages/sso/tsdown.config.ts
5
+ ℹ tsdown v0.17.0 powered by rolldown v1.0.0-beta.53
6
+ ℹ config file: /home/runner/work/better-auth/better-auth/packages/sso/tsdown.config.ts
7
7
  ℹ entry: src/index.ts, src/client.ts
8
8
  ℹ tsconfig: tsconfig.json
9
9
  ℹ Build start
10
- ℹ dist/index.mjs 58.49 kB │ gzip: 10.33 kB
10
+ ℹ dist/index.mjs 58.73 kB │ gzip: 10.41 kB
11
11
  ℹ dist/client.mjs  0.15 kB │ gzip: 0.14 kB
12
- ℹ dist/client.d.mts  0.49 kB │ gzip: 0.29 kB
12
+ ℹ dist/client.d.mts  0.49 kB │ gzip: 0.30 kB
13
13
  ℹ dist/index.d.mts  0.21 kB │ gzip: 0.15 kB
14
- ℹ dist/index-DCyJckhH.d.mts 25.42 kB │ gzip: 3.96 kB
15
- ℹ 5 files, total: 84.77 kB
16
- ✔ Build complete in 11114ms
14
+ ℹ dist/index-D-JmJR9N.d.mts 25.42 kB │ gzip: 3.95 kB
15
+ ℹ 5 files, total: 85.01 kB
16
+ ✔ Build complete in 10982ms
package/dist/client.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { t as SSOPlugin } from "./index-DCyJckhH.mjs";
1
+ import { t as SSOPlugin } from "./index-D-JmJR9N.mjs";
2
2
 
3
3
  //#region src/client.d.ts
4
4
  interface SSOClientOptions {
@@ -1,6 +1,6 @@
1
1
  import * as z from "zod/v4";
2
2
  import { OAuth2Tokens, User } from "better-auth";
3
- import * as better_call7 from "better-call";
3
+ import * as better_call0 from "better-call";
4
4
 
5
5
  //#region src/types.d.ts
6
6
  interface OIDCMapping {
@@ -240,7 +240,7 @@ interface SSOOptions {
240
240
  }
241
241
  //#endregion
242
242
  //#region src/routes/domain-verification.d.ts
243
- declare const requestDomainVerification: (options: SSOOptions) => better_call7.StrictEndpoint<"/sso/request-domain-verification", {
243
+ declare const requestDomainVerification: (options: SSOOptions) => better_call0.StrictEndpoint<"/sso/request-domain-verification", {
244
244
  method: "POST";
245
245
  body: z.ZodObject<{
246
246
  providerId: z.ZodString;
@@ -262,7 +262,7 @@ declare const requestDomainVerification: (options: SSOOptions) => better_call7.S
262
262
  };
263
263
  };
264
264
  };
265
- use: ((inputContext: better_call7.MiddlewareInputContext<better_call7.MiddlewareOptions>) => Promise<{
265
+ use: ((inputContext: better_call0.MiddlewareInputContext<better_call0.MiddlewareOptions>) => Promise<{
266
266
  session: {
267
267
  session: Record<string, any> & {
268
268
  id: string;
@@ -290,7 +290,7 @@ declare const requestDomainVerification: (options: SSOOptions) => better_call7.S
290
290
  }, {
291
291
  domainVerificationToken: string;
292
292
  }>;
293
- declare const verifyDomain: (options: SSOOptions) => better_call7.StrictEndpoint<"/sso/verify-domain", {
293
+ declare const verifyDomain: (options: SSOOptions) => better_call0.StrictEndpoint<"/sso/verify-domain", {
294
294
  method: "POST";
295
295
  body: z.ZodObject<{
296
296
  providerId: z.ZodString;
@@ -315,7 +315,7 @@ declare const verifyDomain: (options: SSOOptions) => better_call7.StrictEndpoint
315
315
  };
316
316
  };
317
317
  };
318
- use: ((inputContext: better_call7.MiddlewareInputContext<better_call7.MiddlewareOptions>) => Promise<{
318
+ use: ((inputContext: better_call0.MiddlewareInputContext<better_call0.MiddlewareOptions>) => Promise<{
319
319
  session: {
320
320
  session: Record<string, any> & {
321
321
  id: string;
@@ -343,7 +343,7 @@ declare const verifyDomain: (options: SSOOptions) => better_call7.StrictEndpoint
343
343
  }, void>;
344
344
  //#endregion
345
345
  //#region src/routes/sso.d.ts
346
- declare const spMetadata: () => better_call7.StrictEndpoint<"/sso/saml2/sp/metadata", {
346
+ declare const spMetadata: () => better_call0.StrictEndpoint<"/sso/saml2/sp/metadata", {
347
347
  method: "GET";
348
348
  query: z.ZodObject<{
349
349
  providerId: z.ZodString;
@@ -367,7 +367,7 @@ declare const spMetadata: () => better_call7.StrictEndpoint<"/sso/saml2/sp/metad
367
367
  } & {
368
368
  use: any[];
369
369
  }, Response>;
370
- declare const registerSSOProvider: <O extends SSOOptions>(options: O) => better_call7.StrictEndpoint<"/sso/register", {
370
+ declare const registerSSOProvider: <O extends SSOOptions>(options: O) => better_call0.StrictEndpoint<"/sso/register", {
371
371
  method: "POST";
372
372
  body: z.ZodObject<{
373
373
  providerId: z.ZodString;
@@ -445,7 +445,7 @@ declare const registerSSOProvider: <O extends SSOOptions>(options: O) => better_
445
445
  organizationId: z.ZodOptional<z.ZodString>;
446
446
  overrideUserInfo: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
447
447
  }, z.core.$strip>;
448
- use: ((inputContext: better_call7.MiddlewareInputContext<better_call7.MiddlewareOptions>) => Promise<{
448
+ use: ((inputContext: better_call0.MiddlewareInputContext<better_call0.MiddlewareOptions>) => Promise<{
449
449
  session: {
450
450
  session: Record<string, any> & {
451
451
  id: string;
@@ -637,7 +637,7 @@ declare const registerSSOProvider: <O extends SSOOptions>(options: O) => better_
637
637
  domainVerified: boolean;
638
638
  domainVerificationToken: string;
639
639
  } & SSOProvider<O> : SSOProvider<O>>;
640
- declare const signInSSO: (options?: SSOOptions) => better_call7.StrictEndpoint<"/sign-in/sso", {
640
+ declare const signInSSO: (options?: SSOOptions) => better_call0.StrictEndpoint<"/sign-in/sso", {
641
641
  method: "POST";
642
642
  body: z.ZodObject<{
643
643
  email: z.ZodOptional<z.ZodString>;
@@ -733,7 +733,7 @@ declare const signInSSO: (options?: SSOOptions) => better_call7.StrictEndpoint<"
733
733
  url: string;
734
734
  redirect: boolean;
735
735
  }>;
736
- declare const callbackSSO: (options?: SSOOptions) => better_call7.StrictEndpoint<"/sso/callback/:providerId", {
736
+ declare const callbackSSO: (options?: SSOOptions) => better_call0.StrictEndpoint<"/sso/callback/:providerId", {
737
737
  method: "GET";
738
738
  query: z.ZodObject<{
739
739
  code: z.ZodOptional<z.ZodString>;
@@ -758,7 +758,7 @@ declare const callbackSSO: (options?: SSOOptions) => better_call7.StrictEndpoint
758
758
  } & {
759
759
  use: any[];
760
760
  }, never>;
761
- declare const callbackSSOSAML: (options?: SSOOptions) => better_call7.StrictEndpoint<"/sso/saml2/callback/:providerId", {
761
+ declare const callbackSSOSAML: (options?: SSOOptions) => better_call0.StrictEndpoint<"/sso/saml2/callback/:providerId", {
762
762
  method: "POST";
763
763
  body: z.ZodObject<{
764
764
  SAMLResponse: z.ZodString;
@@ -787,7 +787,7 @@ declare const callbackSSOSAML: (options?: SSOOptions) => better_call7.StrictEndp
787
787
  } & {
788
788
  use: any[];
789
789
  }, never>;
790
- declare const acsEndpoint: (options?: SSOOptions) => better_call7.StrictEndpoint<"/sso/saml2/sp/acs/:providerId", {
790
+ declare const acsEndpoint: (options?: SSOOptions) => better_call0.StrictEndpoint<"/sso/saml2/sp/acs/:providerId", {
791
791
  method: "POST";
792
792
  params: z.ZodObject<{
793
793
  providerId: z.ZodOptional<z.ZodString>;
package/dist/index.d.mts CHANGED
@@ -1,2 +1,2 @@
1
- import { a as SSOOptions, i as SAMLConfig, n as sso, o as SSOProvider, r as OIDCConfig, t as SSOPlugin } from "./index-DCyJckhH.mjs";
1
+ import { a as SSOOptions, i as SAMLConfig, n as sso, o as SSOProvider, r as OIDCConfig, t as SSOPlugin } from "./index-D-JmJR9N.mjs";
2
2
  export { OIDCConfig, SAMLConfig, SSOOptions, SSOPlugin, SSOProvider, sso };
package/dist/index.mjs CHANGED
@@ -10,10 +10,11 @@ import { handleOAuthUserInfo } from "better-auth/oauth2";
10
10
  import { decodeJwt } from "jose";
11
11
 
12
12
  //#region src/routes/domain-verification.ts
13
+ const domainVerificationBodySchema = z.object({ providerId: z.string() });
13
14
  const requestDomainVerification = (options) => {
14
15
  return createAuthEndpoint("/sso/request-domain-verification", {
15
16
  method: "POST",
16
- body: z.object({ providerId: z.string() }),
17
+ body: domainVerificationBodySchema,
17
18
  metadata: { openapi: {
18
19
  summary: "Request a domain verification",
19
20
  description: "Request a domain verification for the given SSO provider",
@@ -90,7 +91,7 @@ const requestDomainVerification = (options) => {
90
91
  const verifyDomain = (options) => {
91
92
  return createAuthEndpoint("/sso/verify-domain", {
92
93
  method: "POST",
93
- body: z.object({ providerId: z.string() }),
94
+ body: domainVerificationBodySchema,
94
95
  metadata: { openapi: {
95
96
  summary: "Verify the provider domain ownership",
96
97
  description: "Verify the provider domain ownership via DNS records",
@@ -208,13 +209,14 @@ function safeJsonParse(value) {
208
209
  }
209
210
  return null;
210
211
  }
212
+ const spMetadataQuerySchema = z.object({
213
+ providerId: z.string(),
214
+ format: z.enum(["xml", "json"]).default("xml")
215
+ });
211
216
  const spMetadata = () => {
212
217
  return createAuthEndpoint("/sso/saml2/sp/metadata", {
213
218
  method: "GET",
214
- query: z.object({
215
- providerId: z.string(),
216
- format: z.enum(["xml", "json"]).default("xml")
217
- }),
219
+ query: spMetadataQuerySchema,
218
220
  metadata: { openapi: {
219
221
  operationId: "getSSOServiceProviderMetadata",
220
222
  summary: "Get Service Provider metadata",
@@ -244,82 +246,83 @@ const spMetadata = () => {
244
246
  return new Response(sp.getMetadata(), { headers: { "Content-Type": "application/xml" } });
245
247
  });
246
248
  };
249
+ const ssoProviderBodySchema = z.object({
250
+ providerId: z.string({}).meta({ description: "The ID of the provider. This is used to identify the provider during login and callback" }),
251
+ issuer: z.string({}).meta({ description: "The issuer of the provider" }),
252
+ domain: z.string({}).meta({ description: "The domain of the provider. This is used for email matching" }),
253
+ oidcConfig: z.object({
254
+ clientId: z.string({}).meta({ description: "The client ID" }),
255
+ clientSecret: z.string({}).meta({ description: "The client secret" }),
256
+ authorizationEndpoint: z.string({}).meta({ description: "The authorization endpoint" }).optional(),
257
+ tokenEndpoint: z.string({}).meta({ description: "The token endpoint" }).optional(),
258
+ userInfoEndpoint: z.string({}).meta({ description: "The user info endpoint" }).optional(),
259
+ tokenEndpointAuthentication: z.enum(["client_secret_post", "client_secret_basic"]).optional(),
260
+ jwksEndpoint: z.string({}).meta({ description: "The JWKS endpoint" }).optional(),
261
+ discoveryEndpoint: z.string().optional(),
262
+ scopes: z.array(z.string(), {}).meta({ description: "The scopes to request. Defaults to ['openid', 'email', 'profile', 'offline_access']" }).optional(),
263
+ pkce: z.boolean({}).meta({ description: "Whether to use PKCE for the authorization flow" }).default(true).optional(),
264
+ mapping: z.object({
265
+ id: z.string({}).meta({ description: "Field mapping for user ID (defaults to 'sub')" }),
266
+ email: z.string({}).meta({ description: "Field mapping for email (defaults to 'email')" }),
267
+ emailVerified: z.string({}).meta({ description: "Field mapping for email verification (defaults to 'email_verified')" }).optional(),
268
+ name: z.string({}).meta({ description: "Field mapping for name (defaults to 'name')" }),
269
+ image: z.string({}).meta({ description: "Field mapping for image (defaults to 'picture')" }).optional(),
270
+ extraFields: z.record(z.string(), z.any()).optional()
271
+ }).optional()
272
+ }).optional(),
273
+ samlConfig: z.object({
274
+ entryPoint: z.string({}).meta({ description: "The entry point of the provider" }),
275
+ cert: z.string({}).meta({ description: "The certificate of the provider" }),
276
+ callbackUrl: z.string({}).meta({ description: "The callback URL of the provider" }),
277
+ audience: z.string().optional(),
278
+ idpMetadata: z.object({
279
+ metadata: z.string().optional(),
280
+ entityID: z.string().optional(),
281
+ cert: z.string().optional(),
282
+ privateKey: z.string().optional(),
283
+ privateKeyPass: z.string().optional(),
284
+ isAssertionEncrypted: z.boolean().optional(),
285
+ encPrivateKey: z.string().optional(),
286
+ encPrivateKeyPass: z.string().optional(),
287
+ singleSignOnService: z.array(z.object({
288
+ Binding: z.string().meta({ description: "The binding type for the SSO service" }),
289
+ Location: z.string().meta({ description: "The URL for the SSO service" })
290
+ })).optional().meta({ description: "Single Sign-On service configuration" })
291
+ }).optional(),
292
+ spMetadata: z.object({
293
+ metadata: z.string().optional(),
294
+ entityID: z.string().optional(),
295
+ binding: z.string().optional(),
296
+ privateKey: z.string().optional(),
297
+ privateKeyPass: z.string().optional(),
298
+ isAssertionEncrypted: z.boolean().optional(),
299
+ encPrivateKey: z.string().optional(),
300
+ encPrivateKeyPass: z.string().optional()
301
+ }),
302
+ wantAssertionsSigned: z.boolean().optional(),
303
+ signatureAlgorithm: z.string().optional(),
304
+ digestAlgorithm: z.string().optional(),
305
+ identifierFormat: z.string().optional(),
306
+ privateKey: z.string().optional(),
307
+ decryptionPvk: z.string().optional(),
308
+ additionalParams: z.record(z.string(), z.any()).optional(),
309
+ mapping: z.object({
310
+ id: z.string({}).meta({ description: "Field mapping for user ID (defaults to 'nameID')" }),
311
+ email: z.string({}).meta({ description: "Field mapping for email (defaults to 'email')" }),
312
+ emailVerified: z.string({}).meta({ description: "Field mapping for email verification" }).optional(),
313
+ name: z.string({}).meta({ description: "Field mapping for name (defaults to 'displayName')" }),
314
+ firstName: z.string({}).meta({ description: "Field mapping for first name (defaults to 'givenName')" }).optional(),
315
+ lastName: z.string({}).meta({ description: "Field mapping for last name (defaults to 'surname')" }).optional(),
316
+ extraFields: z.record(z.string(), z.any()).optional()
317
+ }).optional()
318
+ }).optional(),
319
+ organizationId: z.string({}).meta({ description: "If organization plugin is enabled, the organization id to link the provider to" }).optional(),
320
+ overrideUserInfo: z.boolean({}).meta({ description: "Override user info with the provider info. Defaults to false" }).default(false).optional()
321
+ });
247
322
  const registerSSOProvider = (options) => {
248
323
  return createAuthEndpoint("/sso/register", {
249
324
  method: "POST",
250
- body: z.object({
251
- providerId: z.string({}).meta({ description: "The ID of the provider. This is used to identify the provider during login and callback" }),
252
- issuer: z.string({}).meta({ description: "The issuer of the provider" }),
253
- domain: z.string({}).meta({ description: "The domain of the provider. This is used for email matching" }),
254
- oidcConfig: z.object({
255
- clientId: z.string({}).meta({ description: "The client ID" }),
256
- clientSecret: z.string({}).meta({ description: "The client secret" }),
257
- authorizationEndpoint: z.string({}).meta({ description: "The authorization endpoint" }).optional(),
258
- tokenEndpoint: z.string({}).meta({ description: "The token endpoint" }).optional(),
259
- userInfoEndpoint: z.string({}).meta({ description: "The user info endpoint" }).optional(),
260
- tokenEndpointAuthentication: z.enum(["client_secret_post", "client_secret_basic"]).optional(),
261
- jwksEndpoint: z.string({}).meta({ description: "The JWKS endpoint" }).optional(),
262
- discoveryEndpoint: z.string().optional(),
263
- scopes: z.array(z.string(), {}).meta({ description: "The scopes to request. Defaults to ['openid', 'email', 'profile', 'offline_access']" }).optional(),
264
- pkce: z.boolean({}).meta({ description: "Whether to use PKCE for the authorization flow" }).default(true).optional(),
265
- mapping: z.object({
266
- id: z.string({}).meta({ description: "Field mapping for user ID (defaults to 'sub')" }),
267
- email: z.string({}).meta({ description: "Field mapping for email (defaults to 'email')" }),
268
- emailVerified: z.string({}).meta({ description: "Field mapping for email verification (defaults to 'email_verified')" }).optional(),
269
- name: z.string({}).meta({ description: "Field mapping for name (defaults to 'name')" }),
270
- image: z.string({}).meta({ description: "Field mapping for image (defaults to 'picture')" }).optional(),
271
- extraFields: z.record(z.string(), z.any()).optional()
272
- }).optional()
273
- }).optional(),
274
- samlConfig: z.object({
275
- entryPoint: z.string({}).meta({ description: "The entry point of the provider" }),
276
- cert: z.string({}).meta({ description: "The certificate of the provider" }),
277
- callbackUrl: z.string({}).meta({ description: "The callback URL of the provider" }),
278
- audience: z.string().optional(),
279
- idpMetadata: z.object({
280
- metadata: z.string().optional(),
281
- entityID: z.string().optional(),
282
- cert: z.string().optional(),
283
- privateKey: z.string().optional(),
284
- privateKeyPass: z.string().optional(),
285
- isAssertionEncrypted: z.boolean().optional(),
286
- encPrivateKey: z.string().optional(),
287
- encPrivateKeyPass: z.string().optional(),
288
- singleSignOnService: z.array(z.object({
289
- Binding: z.string().meta({ description: "The binding type for the SSO service" }),
290
- Location: z.string().meta({ description: "The URL for the SSO service" })
291
- })).optional().meta({ description: "Single Sign-On service configuration" })
292
- }).optional(),
293
- spMetadata: z.object({
294
- metadata: z.string().optional(),
295
- entityID: z.string().optional(),
296
- binding: z.string().optional(),
297
- privateKey: z.string().optional(),
298
- privateKeyPass: z.string().optional(),
299
- isAssertionEncrypted: z.boolean().optional(),
300
- encPrivateKey: z.string().optional(),
301
- encPrivateKeyPass: z.string().optional()
302
- }),
303
- wantAssertionsSigned: z.boolean().optional(),
304
- signatureAlgorithm: z.string().optional(),
305
- digestAlgorithm: z.string().optional(),
306
- identifierFormat: z.string().optional(),
307
- privateKey: z.string().optional(),
308
- decryptionPvk: z.string().optional(),
309
- additionalParams: z.record(z.string(), z.any()).optional(),
310
- mapping: z.object({
311
- id: z.string({}).meta({ description: "Field mapping for user ID (defaults to 'nameID')" }),
312
- email: z.string({}).meta({ description: "Field mapping for email (defaults to 'email')" }),
313
- emailVerified: z.string({}).meta({ description: "Field mapping for email verification" }).optional(),
314
- name: z.string({}).meta({ description: "Field mapping for name (defaults to 'displayName')" }),
315
- firstName: z.string({}).meta({ description: "Field mapping for first name (defaults to 'givenName')" }).optional(),
316
- lastName: z.string({}).meta({ description: "Field mapping for last name (defaults to 'surname')" }).optional(),
317
- extraFields: z.record(z.string(), z.any()).optional()
318
- }).optional()
319
- }).optional(),
320
- organizationId: z.string({}).meta({ description: "If organization plugin is enabled, the organization id to link the provider to" }).optional(),
321
- overrideUserInfo: z.boolean({}).meta({ description: "Override user info with the provider info. Defaults to false" }).default(false).optional()
322
- }),
325
+ body: ssoProviderBodySchema,
323
326
  use: [sessionMiddleware],
324
327
  metadata: { openapi: {
325
328
  operationId: "registerSSOProvider",
@@ -592,22 +595,23 @@ const registerSSOProvider = (options) => {
592
595
  });
593
596
  });
594
597
  };
598
+ const signInSSOBodySchema = z.object({
599
+ email: z.string({}).meta({ description: "The email address to sign in with. This is used to identify the issuer to sign in with. It's optional if the issuer is provided" }).optional(),
600
+ organizationSlug: z.string({}).meta({ description: "The slug of the organization to sign in with" }).optional(),
601
+ providerId: z.string({}).meta({ description: "The ID of the provider to sign in with. This can be provided instead of email or issuer" }).optional(),
602
+ domain: z.string({}).meta({ description: "The domain of the provider." }).optional(),
603
+ callbackURL: z.string({}).meta({ description: "The URL to redirect to after login" }),
604
+ errorCallbackURL: z.string({}).meta({ description: "The URL to redirect to after login" }).optional(),
605
+ newUserCallbackURL: z.string({}).meta({ description: "The URL to redirect to after login if the user is new" }).optional(),
606
+ scopes: z.array(z.string(), {}).meta({ description: "Scopes to request from the provider." }).optional(),
607
+ loginHint: z.string({}).meta({ description: "Login hint to send to the identity provider (e.g., email or identifier). If supported, will be sent as 'login_hint'." }).optional(),
608
+ requestSignUp: z.boolean({}).meta({ description: "Explicitly request sign-up. Useful when disableImplicitSignUp is true for this provider" }).optional(),
609
+ providerType: z.enum(["oidc", "saml"]).optional()
610
+ });
595
611
  const signInSSO = (options) => {
596
612
  return createAuthEndpoint("/sign-in/sso", {
597
613
  method: "POST",
598
- body: z.object({
599
- email: z.string({}).meta({ description: "The email address to sign in with. This is used to identify the issuer to sign in with. It's optional if the issuer is provided" }).optional(),
600
- organizationSlug: z.string({}).meta({ description: "The slug of the organization to sign in with" }).optional(),
601
- providerId: z.string({}).meta({ description: "The ID of the provider to sign in with. This can be provided instead of email or issuer" }).optional(),
602
- domain: z.string({}).meta({ description: "The domain of the provider." }).optional(),
603
- callbackURL: z.string({}).meta({ description: "The URL to redirect to after login" }),
604
- errorCallbackURL: z.string({}).meta({ description: "The URL to redirect to after login" }).optional(),
605
- newUserCallbackURL: z.string({}).meta({ description: "The URL to redirect to after login if the user is new" }).optional(),
606
- scopes: z.array(z.string(), {}).meta({ description: "Scopes to request from the provider." }).optional(),
607
- loginHint: z.string({}).meta({ description: "Login hint to send to the identity provider (e.g., email or identifier). If supported, will be sent as 'login_hint'." }).optional(),
608
- requestSignUp: z.boolean({}).meta({ description: "Explicitly request sign-up. Useful when disableImplicitSignUp is true for this provider" }).optional(),
609
- providerType: z.enum(["oidc", "saml"]).optional()
610
- }),
614
+ body: signInSSOBodySchema,
611
615
  metadata: { openapi: {
612
616
  operationId: "signInWithSSO",
613
617
  summary: "Sign in with SSO provider",
@@ -781,15 +785,16 @@ const signInSSO = (options) => {
781
785
  throw new APIError("BAD_REQUEST", { message: "Invalid SSO provider" });
782
786
  });
783
787
  };
788
+ const callbackSSOQuerySchema = z.object({
789
+ code: z.string().optional(),
790
+ state: z.string(),
791
+ error: z.string().optional(),
792
+ error_description: z.string().optional()
793
+ });
784
794
  const callbackSSO = (options) => {
785
795
  return createAuthEndpoint("/sso/callback/:providerId", {
786
796
  method: "GET",
787
- query: z.object({
788
- code: z.string().optional(),
789
- state: z.string(),
790
- error: z.string().optional(),
791
- error_description: z.string().optional()
792
- }),
797
+ query: callbackSSOQuerySchema,
793
798
  allowedMediaTypes: ["application/x-www-form-urlencoded", "application/json"],
794
799
  metadata: {
795
800
  isAction: false,
@@ -966,13 +971,14 @@ const callbackSSO = (options) => {
966
971
  throw ctx.redirect(toRedirectTo);
967
972
  });
968
973
  };
974
+ const callbackSSOSAMLBodySchema = z.object({
975
+ SAMLResponse: z.string(),
976
+ RelayState: z.string().optional()
977
+ });
969
978
  const callbackSSOSAML = (options) => {
970
979
  return createAuthEndpoint("/sso/saml2/callback/:providerId", {
971
980
  method: "POST",
972
- body: z.object({
973
- SAMLResponse: z.string(),
974
- RelayState: z.string().optional()
975
- }),
981
+ body: callbackSSOSAMLBodySchema,
976
982
  metadata: {
977
983
  isAction: false,
978
984
  allowedMediaTypes: ["application/x-www-form-urlencoded", "application/json"],
@@ -1186,14 +1192,16 @@ const callbackSSOSAML = (options) => {
1186
1192
  throw ctx.redirect(callbackUrl);
1187
1193
  });
1188
1194
  };
1195
+ const acsEndpointParamsSchema = z.object({ providerId: z.string().optional() });
1196
+ const acsEndpointBodySchema = z.object({
1197
+ SAMLResponse: z.string(),
1198
+ RelayState: z.string().optional()
1199
+ });
1189
1200
  const acsEndpoint = (options) => {
1190
1201
  return createAuthEndpoint("/sso/saml2/sp/acs/:providerId", {
1191
1202
  method: "POST",
1192
- params: z.object({ providerId: z.string().optional() }),
1193
- body: z.object({
1194
- SAMLResponse: z.string(),
1195
- RelayState: z.string().optional()
1196
- }),
1203
+ params: acsEndpointParamsSchema,
1204
+ body: acsEndpointBodySchema,
1197
1205
  metadata: {
1198
1206
  isAction: false,
1199
1207
  allowedMediaTypes: ["application/x-www-form-urlencoded", "application/json"],
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@better-auth/sso",
3
3
  "author": "Bereket Engida",
4
- "version": "1.4.6-beta.2",
4
+ "version": "1.4.6-beta.3",
5
5
  "type": "module",
6
6
  "main": "dist/index.mjs",
7
7
  "homepage": "https://www.better-auth.com/docs/plugins/sso",
@@ -64,11 +64,11 @@
64
64
  "body-parser": "^2.2.1",
65
65
  "express": "^5.1.0",
66
66
  "oauth2-mock-server": "^8.2.0",
67
- "tsdown": "^0.16.0",
68
- "better-auth": "1.4.6-beta.2"
67
+ "tsdown": "^0.17.0",
68
+ "better-auth": "1.4.6-beta.3"
69
69
  },
70
70
  "peerDependencies": {
71
- "better-auth": "1.4.6-beta.2"
71
+ "better-auth": "1.4.6-beta.3"
72
72
  },
73
73
  "scripts": {
74
74
  "test": "vitest",
@@ -8,14 +8,16 @@ import { generateRandomString } from "better-auth/crypto";
8
8
  import * as z from "zod/v4";
9
9
  import type { SSOOptions, SSOProvider } from "../types";
10
10
 
11
+ const domainVerificationBodySchema = z.object({
12
+ providerId: z.string(),
13
+ });
14
+
11
15
  export const requestDomainVerification = (options: SSOOptions) => {
12
16
  return createAuthEndpoint(
13
17
  "/sso/request-domain-verification",
14
18
  {
15
19
  method: "POST",
16
- body: z.object({
17
- providerId: z.string(),
18
- }),
20
+ body: domainVerificationBodySchema,
19
21
  metadata: {
20
22
  openapi: {
21
23
  summary: "Request a domain verification",
@@ -127,9 +129,7 @@ export const verifyDomain = (options: SSOOptions) => {
127
129
  "/sso/verify-domain",
128
130
  {
129
131
  method: "POST",
130
- body: z.object({
131
- providerId: z.string(),
132
- }),
132
+ body: domainVerificationBodySchema,
133
133
  metadata: {
134
134
  openapi: {
135
135
  summary: "Verify the provider domain ownership",
package/src/routes/sso.ts CHANGED
@@ -52,15 +52,17 @@ function safeJsonParse<T>(value: string | T | null | undefined): T | null {
52
52
  return null;
53
53
  }
54
54
 
55
+ const spMetadataQuerySchema = z.object({
56
+ providerId: z.string(),
57
+ format: z.enum(["xml", "json"]).default("xml"),
58
+ });
59
+
55
60
  export const spMetadata = () => {
56
61
  return createAuthEndpoint(
57
62
  "/sso/saml2/sp/metadata",
58
63
  {
59
64
  method: "GET",
60
- query: z.object({
61
- providerId: z.string(),
62
- format: z.enum(["xml", "json"]).default("xml"),
63
- }),
65
+ query: spMetadataQuerySchema,
64
66
  metadata: {
65
67
  openapi: {
66
68
  operationId: "getSSOServiceProviderMetadata",
@@ -128,213 +130,211 @@ export const spMetadata = () => {
128
130
  );
129
131
  };
130
132
 
131
- export const registerSSOProvider = <O extends SSOOptions>(options: O) => {
132
- return createAuthEndpoint(
133
- "/sso/register",
134
- {
135
- method: "POST",
136
- body: z.object({
137
- providerId: z.string({}).meta({
138
- description:
139
- "The ID of the provider. This is used to identify the provider during login and callback",
140
- }),
141
- issuer: z.string({}).meta({
142
- description: "The issuer of the provider",
143
- }),
144
- domain: z.string({}).meta({
133
+ const ssoProviderBodySchema = z.object({
134
+ providerId: z.string({}).meta({
135
+ description:
136
+ "The ID of the provider. This is used to identify the provider during login and callback",
137
+ }),
138
+ issuer: z.string({}).meta({
139
+ description: "The issuer of the provider",
140
+ }),
141
+ domain: z.string({}).meta({
142
+ description: "The domain of the provider. This is used for email matching",
143
+ }),
144
+ oidcConfig: z
145
+ .object({
146
+ clientId: z.string({}).meta({
147
+ description: "The client ID",
148
+ }),
149
+ clientSecret: z.string({}).meta({
150
+ description: "The client secret",
151
+ }),
152
+ authorizationEndpoint: z
153
+ .string({})
154
+ .meta({
155
+ description: "The authorization endpoint",
156
+ })
157
+ .optional(),
158
+ tokenEndpoint: z
159
+ .string({})
160
+ .meta({
161
+ description: "The token endpoint",
162
+ })
163
+ .optional(),
164
+ userInfoEndpoint: z
165
+ .string({})
166
+ .meta({
167
+ description: "The user info endpoint",
168
+ })
169
+ .optional(),
170
+ tokenEndpointAuthentication: z
171
+ .enum(["client_secret_post", "client_secret_basic"])
172
+ .optional(),
173
+ jwksEndpoint: z
174
+ .string({})
175
+ .meta({
176
+ description: "The JWKS endpoint",
177
+ })
178
+ .optional(),
179
+ discoveryEndpoint: z.string().optional(),
180
+ scopes: z
181
+ .array(z.string(), {})
182
+ .meta({
145
183
  description:
146
- "The domain of the provider. This is used for email matching",
147
- }),
148
- oidcConfig: z
149
- .object({
150
- clientId: z.string({}).meta({
151
- description: "The client ID",
152
- }),
153
- clientSecret: z.string({}).meta({
154
- description: "The client secret",
155
- }),
156
- authorizationEndpoint: z
157
- .string({})
158
- .meta({
159
- description: "The authorization endpoint",
160
- })
161
- .optional(),
162
- tokenEndpoint: z
163
- .string({})
164
- .meta({
165
- description: "The token endpoint",
166
- })
167
- .optional(),
168
- userInfoEndpoint: z
169
- .string({})
170
- .meta({
171
- description: "The user info endpoint",
172
- })
173
- .optional(),
174
- tokenEndpointAuthentication: z
175
- .enum(["client_secret_post", "client_secret_basic"])
176
- .optional(),
177
- jwksEndpoint: z
178
- .string({})
179
- .meta({
180
- description: "The JWKS endpoint",
181
- })
182
- .optional(),
183
- discoveryEndpoint: z.string().optional(),
184
- scopes: z
185
- .array(z.string(), {})
186
- .meta({
187
- description:
188
- "The scopes to request. Defaults to ['openid', 'email', 'profile', 'offline_access']",
189
- })
190
- .optional(),
191
- pkce: z
192
- .boolean({})
193
- .meta({
194
- description: "Whether to use PKCE for the authorization flow",
195
- })
196
- .default(true)
197
- .optional(),
198
- mapping: z
199
- .object({
200
- id: z.string({}).meta({
201
- description: "Field mapping for user ID (defaults to 'sub')",
202
- }),
203
- email: z.string({}).meta({
204
- description: "Field mapping for email (defaults to 'email')",
184
+ "The scopes to request. Defaults to ['openid', 'email', 'profile', 'offline_access']",
185
+ })
186
+ .optional(),
187
+ pkce: z
188
+ .boolean({})
189
+ .meta({
190
+ description: "Whether to use PKCE for the authorization flow",
191
+ })
192
+ .default(true)
193
+ .optional(),
194
+ mapping: z
195
+ .object({
196
+ id: z.string({}).meta({
197
+ description: "Field mapping for user ID (defaults to 'sub')",
198
+ }),
199
+ email: z.string({}).meta({
200
+ description: "Field mapping for email (defaults to 'email')",
201
+ }),
202
+ emailVerified: z
203
+ .string({})
204
+ .meta({
205
+ description:
206
+ "Field mapping for email verification (defaults to 'email_verified')",
207
+ })
208
+ .optional(),
209
+ name: z.string({}).meta({
210
+ description: "Field mapping for name (defaults to 'name')",
211
+ }),
212
+ image: z
213
+ .string({})
214
+ .meta({
215
+ description: "Field mapping for image (defaults to 'picture')",
216
+ })
217
+ .optional(),
218
+ extraFields: z.record(z.string(), z.any()).optional(),
219
+ })
220
+ .optional(),
221
+ })
222
+ .optional(),
223
+ samlConfig: z
224
+ .object({
225
+ entryPoint: z.string({}).meta({
226
+ description: "The entry point of the provider",
227
+ }),
228
+ cert: z.string({}).meta({
229
+ description: "The certificate of the provider",
230
+ }),
231
+ callbackUrl: z.string({}).meta({
232
+ description: "The callback URL of the provider",
233
+ }),
234
+ audience: z.string().optional(),
235
+ idpMetadata: z
236
+ .object({
237
+ metadata: z.string().optional(),
238
+ entityID: z.string().optional(),
239
+ cert: z.string().optional(),
240
+ privateKey: z.string().optional(),
241
+ privateKeyPass: z.string().optional(),
242
+ isAssertionEncrypted: z.boolean().optional(),
243
+ encPrivateKey: z.string().optional(),
244
+ encPrivateKeyPass: z.string().optional(),
245
+ singleSignOnService: z
246
+ .array(
247
+ z.object({
248
+ Binding: z.string().meta({
249
+ description: "The binding type for the SSO service",
205
250
  }),
206
- emailVerified: z
207
- .string({})
208
- .meta({
209
- description:
210
- "Field mapping for email verification (defaults to 'email_verified')",
211
- })
212
- .optional(),
213
- name: z.string({}).meta({
214
- description: "Field mapping for name (defaults to 'name')",
251
+ Location: z.string().meta({
252
+ description: "The URL for the SSO service",
215
253
  }),
216
- image: z
217
- .string({})
218
- .meta({
219
- description:
220
- "Field mapping for image (defaults to 'picture')",
221
- })
222
- .optional(),
223
- extraFields: z.record(z.string(), z.any()).optional(),
224
- })
225
- .optional(),
226
- })
227
- .optional(),
228
- samlConfig: z
229
- .object({
230
- entryPoint: z.string({}).meta({
231
- description: "The entry point of the provider",
232
- }),
233
- cert: z.string({}).meta({
234
- description: "The certificate of the provider",
235
- }),
236
- callbackUrl: z.string({}).meta({
237
- description: "The callback URL of the provider",
238
- }),
239
- audience: z.string().optional(),
240
- idpMetadata: z
241
- .object({
242
- metadata: z.string().optional(),
243
- entityID: z.string().optional(),
244
- cert: z.string().optional(),
245
- privateKey: z.string().optional(),
246
- privateKeyPass: z.string().optional(),
247
- isAssertionEncrypted: z.boolean().optional(),
248
- encPrivateKey: z.string().optional(),
249
- encPrivateKeyPass: z.string().optional(),
250
- singleSignOnService: z
251
- .array(
252
- z.object({
253
- Binding: z.string().meta({
254
- description: "The binding type for the SSO service",
255
- }),
256
- Location: z.string().meta({
257
- description: "The URL for the SSO service",
258
- }),
259
- }),
260
- )
261
- .optional()
262
- .meta({
263
- description: "Single Sign-On service configuration",
264
- }),
265
- })
266
- .optional(),
267
- spMetadata: z.object({
268
- metadata: z.string().optional(),
269
- entityID: z.string().optional(),
270
- binding: z.string().optional(),
271
- privateKey: z.string().optional(),
272
- privateKeyPass: z.string().optional(),
273
- isAssertionEncrypted: z.boolean().optional(),
274
- encPrivateKey: z.string().optional(),
275
- encPrivateKeyPass: z.string().optional(),
254
+ }),
255
+ )
256
+ .optional()
257
+ .meta({
258
+ description: "Single Sign-On service configuration",
276
259
  }),
277
- wantAssertionsSigned: z.boolean().optional(),
278
- signatureAlgorithm: z.string().optional(),
279
- digestAlgorithm: z.string().optional(),
280
- identifierFormat: z.string().optional(),
281
- privateKey: z.string().optional(),
282
- decryptionPvk: z.string().optional(),
283
- additionalParams: z.record(z.string(), z.any()).optional(),
284
- mapping: z
285
- .object({
286
- id: z.string({}).meta({
287
- description:
288
- "Field mapping for user ID (defaults to 'nameID')",
289
- }),
290
- email: z.string({}).meta({
291
- description: "Field mapping for email (defaults to 'email')",
292
- }),
293
- emailVerified: z
294
- .string({})
295
- .meta({
296
- description: "Field mapping for email verification",
297
- })
298
- .optional(),
299
- name: z.string({}).meta({
300
- description:
301
- "Field mapping for name (defaults to 'displayName')",
302
- }),
303
- firstName: z
304
- .string({})
305
- .meta({
306
- description:
307
- "Field mapping for first name (defaults to 'givenName')",
308
- })
309
- .optional(),
310
- lastName: z
311
- .string({})
312
- .meta({
313
- description:
314
- "Field mapping for last name (defaults to 'surname')",
315
- })
316
- .optional(),
317
- extraFields: z.record(z.string(), z.any()).optional(),
318
- })
319
- .optional(),
320
- })
321
- .optional(),
322
- organizationId: z
323
- .string({})
324
- .meta({
325
- description:
326
- "If organization plugin is enabled, the organization id to link the provider to",
327
- })
328
- .optional(),
329
- overrideUserInfo: z
330
- .boolean({})
331
- .meta({
332
- description:
333
- "Override user info with the provider info. Defaults to false",
334
- })
335
- .default(false)
336
- .optional(),
260
+ })
261
+ .optional(),
262
+ spMetadata: z.object({
263
+ metadata: z.string().optional(),
264
+ entityID: z.string().optional(),
265
+ binding: z.string().optional(),
266
+ privateKey: z.string().optional(),
267
+ privateKeyPass: z.string().optional(),
268
+ isAssertionEncrypted: z.boolean().optional(),
269
+ encPrivateKey: z.string().optional(),
270
+ encPrivateKeyPass: z.string().optional(),
337
271
  }),
272
+ wantAssertionsSigned: z.boolean().optional(),
273
+ signatureAlgorithm: z.string().optional(),
274
+ digestAlgorithm: z.string().optional(),
275
+ identifierFormat: z.string().optional(),
276
+ privateKey: z.string().optional(),
277
+ decryptionPvk: z.string().optional(),
278
+ additionalParams: z.record(z.string(), z.any()).optional(),
279
+ mapping: z
280
+ .object({
281
+ id: z.string({}).meta({
282
+ description: "Field mapping for user ID (defaults to 'nameID')",
283
+ }),
284
+ email: z.string({}).meta({
285
+ description: "Field mapping for email (defaults to 'email')",
286
+ }),
287
+ emailVerified: z
288
+ .string({})
289
+ .meta({
290
+ description: "Field mapping for email verification",
291
+ })
292
+ .optional(),
293
+ name: z.string({}).meta({
294
+ description: "Field mapping for name (defaults to 'displayName')",
295
+ }),
296
+ firstName: z
297
+ .string({})
298
+ .meta({
299
+ description:
300
+ "Field mapping for first name (defaults to 'givenName')",
301
+ })
302
+ .optional(),
303
+ lastName: z
304
+ .string({})
305
+ .meta({
306
+ description:
307
+ "Field mapping for last name (defaults to 'surname')",
308
+ })
309
+ .optional(),
310
+ extraFields: z.record(z.string(), z.any()).optional(),
311
+ })
312
+ .optional(),
313
+ })
314
+ .optional(),
315
+ organizationId: z
316
+ .string({})
317
+ .meta({
318
+ description:
319
+ "If organization plugin is enabled, the organization id to link the provider to",
320
+ })
321
+ .optional(),
322
+ overrideUserInfo: z
323
+ .boolean({})
324
+ .meta({
325
+ description:
326
+ "Override user info with the provider info. Defaults to false",
327
+ })
328
+ .default(false)
329
+ .optional(),
330
+ });
331
+
332
+ export const registerSSOProvider = <O extends SSOOptions>(options: O) => {
333
+ return createAuthEndpoint(
334
+ "/sso/register",
335
+ {
336
+ method: "POST",
337
+ body: ssoProviderBodySchema,
338
338
  use: [sessionMiddleware],
339
339
  metadata: {
340
340
  openapi: {
@@ -699,76 +699,77 @@ export const registerSSOProvider = <O extends SSOOptions>(options: O) => {
699
699
  );
700
700
  };
701
701
 
702
+ const signInSSOBodySchema = z.object({
703
+ email: z
704
+ .string({})
705
+ .meta({
706
+ description:
707
+ "The email address to sign in with. This is used to identify the issuer to sign in with. It's optional if the issuer is provided",
708
+ })
709
+ .optional(),
710
+ organizationSlug: z
711
+ .string({})
712
+ .meta({
713
+ description: "The slug of the organization to sign in with",
714
+ })
715
+ .optional(),
716
+ providerId: z
717
+ .string({})
718
+ .meta({
719
+ description:
720
+ "The ID of the provider to sign in with. This can be provided instead of email or issuer",
721
+ })
722
+ .optional(),
723
+ domain: z
724
+ .string({})
725
+ .meta({
726
+ description: "The domain of the provider.",
727
+ })
728
+ .optional(),
729
+ callbackURL: z.string({}).meta({
730
+ description: "The URL to redirect to after login",
731
+ }),
732
+ errorCallbackURL: z
733
+ .string({})
734
+ .meta({
735
+ description: "The URL to redirect to after login",
736
+ })
737
+ .optional(),
738
+ newUserCallbackURL: z
739
+ .string({})
740
+ .meta({
741
+ description: "The URL to redirect to after login if the user is new",
742
+ })
743
+ .optional(),
744
+ scopes: z
745
+ .array(z.string(), {})
746
+ .meta({
747
+ description: "Scopes to request from the provider.",
748
+ })
749
+ .optional(),
750
+ loginHint: z
751
+ .string({})
752
+ .meta({
753
+ description:
754
+ "Login hint to send to the identity provider (e.g., email or identifier). If supported, will be sent as 'login_hint'.",
755
+ })
756
+ .optional(),
757
+ requestSignUp: z
758
+ .boolean({})
759
+ .meta({
760
+ description:
761
+ "Explicitly request sign-up. Useful when disableImplicitSignUp is true for this provider",
762
+ })
763
+ .optional(),
764
+ providerType: z.enum(["oidc", "saml"]).optional(),
765
+ });
766
+
702
767
  export const signInSSO = (options?: SSOOptions) => {
703
768
  return createAuthEndpoint(
704
769
  "/sign-in/sso",
705
770
  {
706
771
  method: "POST",
707
- body: z.object({
708
- email: z
709
- .string({})
710
- .meta({
711
- description:
712
- "The email address to sign in with. This is used to identify the issuer to sign in with. It's optional if the issuer is provided",
713
- })
714
- .optional(),
715
- organizationSlug: z
716
- .string({})
717
- .meta({
718
- description: "The slug of the organization to sign in with",
719
- })
720
- .optional(),
721
- providerId: z
722
- .string({})
723
- .meta({
724
- description:
725
- "The ID of the provider to sign in with. This can be provided instead of email or issuer",
726
- })
727
- .optional(),
728
- domain: z
729
- .string({})
730
- .meta({
731
- description: "The domain of the provider.",
732
- })
733
- .optional(),
734
- callbackURL: z.string({}).meta({
735
- description: "The URL to redirect to after login",
736
- }),
737
- errorCallbackURL: z
738
- .string({})
739
- .meta({
740
- description: "The URL to redirect to after login",
741
- })
742
- .optional(),
743
- newUserCallbackURL: z
744
- .string({})
745
- .meta({
746
- description:
747
- "The URL to redirect to after login if the user is new",
748
- })
749
- .optional(),
750
- scopes: z
751
- .array(z.string(), {})
752
- .meta({
753
- description: "Scopes to request from the provider.",
754
- })
755
- .optional(),
756
- loginHint: z
757
- .string({})
758
- .meta({
759
- description:
760
- "Login hint to send to the identity provider (e.g., email or identifier). If supported, will be sent as 'login_hint'.",
761
- })
762
- .optional(),
763
- requestSignUp: z
764
- .boolean({})
765
- .meta({
766
- description:
767
- "Explicitly request sign-up. Useful when disableImplicitSignUp is true for this provider",
768
- })
769
- .optional(),
770
- providerType: z.enum(["oidc", "saml"]).optional(),
771
- }),
772
+ body: signInSSOBodySchema,
772
773
  metadata: {
773
774
  openapi: {
774
775
  operationId: "signInWithSSO",
@@ -1101,17 +1102,19 @@ export const signInSSO = (options?: SSOOptions) => {
1101
1102
  );
1102
1103
  };
1103
1104
 
1105
+ const callbackSSOQuerySchema = z.object({
1106
+ code: z.string().optional(),
1107
+ state: z.string(),
1108
+ error: z.string().optional(),
1109
+ error_description: z.string().optional(),
1110
+ });
1111
+
1104
1112
  export const callbackSSO = (options?: SSOOptions) => {
1105
1113
  return createAuthEndpoint(
1106
1114
  "/sso/callback/:providerId",
1107
1115
  {
1108
1116
  method: "GET",
1109
- query: z.object({
1110
- code: z.string().optional(),
1111
- state: z.string(),
1112
- error: z.string().optional(),
1113
- error_description: z.string().optional(),
1114
- }),
1117
+ query: callbackSSOQuerySchema,
1115
1118
  allowedMediaTypes: [
1116
1119
  "application/x-www-form-urlencoded",
1117
1120
  "application/json",
@@ -1468,15 +1471,17 @@ export const callbackSSO = (options?: SSOOptions) => {
1468
1471
  );
1469
1472
  };
1470
1473
 
1474
+ const callbackSSOSAMLBodySchema = z.object({
1475
+ SAMLResponse: z.string(),
1476
+ RelayState: z.string().optional(),
1477
+ });
1478
+
1471
1479
  export const callbackSSOSAML = (options?: SSOOptions) => {
1472
1480
  return createAuthEndpoint(
1473
1481
  "/sso/saml2/callback/:providerId",
1474
1482
  {
1475
1483
  method: "POST",
1476
- body: z.object({
1477
- SAMLResponse: z.string(),
1478
- RelayState: z.string().optional(),
1479
- }),
1484
+ body: callbackSSOSAMLBodySchema,
1480
1485
  metadata: {
1481
1486
  isAction: false,
1482
1487
  allowedMediaTypes: [
@@ -1815,18 +1820,22 @@ export const callbackSSOSAML = (options?: SSOOptions) => {
1815
1820
  );
1816
1821
  };
1817
1822
 
1823
+ const acsEndpointParamsSchema = z.object({
1824
+ providerId: z.string().optional(),
1825
+ });
1826
+
1827
+ const acsEndpointBodySchema = z.object({
1828
+ SAMLResponse: z.string(),
1829
+ RelayState: z.string().optional(),
1830
+ });
1831
+
1818
1832
  export const acsEndpoint = (options?: SSOOptions) => {
1819
1833
  return createAuthEndpoint(
1820
1834
  "/sso/saml2/sp/acs/:providerId",
1821
1835
  {
1822
1836
  method: "POST",
1823
- params: z.object({
1824
- providerId: z.string().optional(),
1825
- }),
1826
- body: z.object({
1827
- SAMLResponse: z.string(),
1828
- RelayState: z.string().optional(),
1829
- }),
1837
+ params: acsEndpointParamsSchema,
1838
+ body: acsEndpointBodySchema,
1830
1839
  metadata: {
1831
1840
  isAction: false,
1832
1841
  allowedMediaTypes: [