@better-auth/sso 1.4.6 → 1.4.7-beta.2
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.
- package/.turbo/turbo-build.log +6 -6
- package/dist/client.d.mts +1 -1
- package/dist/{index-D-JmJR9N.d.mts → index-BWvN4yrs.d.mts} +18 -12
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +5 -4
- package/src/routes/sso.ts +1 -1
- package/src/saml.test.ts +10 -32
- package/src/types.ts +6 -0
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
|
|
2
|
-
> @better-auth/sso@1.4.
|
|
2
|
+
> @better-auth/sso@1.4.7-beta.2 build /home/runner/work/better-auth/better-auth/packages/sso
|
|
3
3
|
> tsdown
|
|
4
4
|
|
|
5
|
-
[34mℹ[39m tsdown [2mv0.17.
|
|
5
|
+
[34mℹ[39m tsdown [2mv0.17.2[22m powered by rolldown [2mv1.0.0-beta.53[22m
|
|
6
6
|
[34mℹ[39m config file: [4m/home/runner/work/better-auth/better-auth/packages/sso/tsdown.config.ts[24m
|
|
7
7
|
[34mℹ[39m entry: [34msrc/index.ts, src/client.ts[39m
|
|
8
8
|
[34mℹ[39m tsconfig: [34mtsconfig.json[39m
|
|
9
9
|
[34mℹ[39m Build start
|
|
10
|
-
[34mℹ[39m [2mdist/[22m[1mindex.mjs[22m [2m59.70 kB[22m [2m│ gzip: 10.
|
|
10
|
+
[34mℹ[39m [2mdist/[22m[1mindex.mjs[22m [2m59.70 kB[22m [2m│ gzip: 10.48 kB[22m
|
|
11
11
|
[34mℹ[39m [2mdist/[22m[1mclient.mjs[22m [2m 0.15 kB[22m [2m│ gzip: 0.14 kB[22m
|
|
12
12
|
[34mℹ[39m [2mdist/[22m[32m[1mclient.d.mts[22m[39m [2m 0.49 kB[22m [2m│ gzip: 0.30 kB[22m
|
|
13
13
|
[34mℹ[39m [2mdist/[22m[32m[1mindex.d.mts[22m[39m [2m 0.21 kB[22m [2m│ gzip: 0.15 kB[22m
|
|
14
|
-
[34mℹ[39m [2mdist/[22m[32mindex-
|
|
15
|
-
[34mℹ[39m 5 files, total:
|
|
16
|
-
[32m✔[39m Build complete in [
|
|
14
|
+
[34mℹ[39m [2mdist/[22m[32mindex-BWvN4yrs.d.mts[39m [2m25.84 kB[22m [2m│ gzip: 4.13 kB[22m
|
|
15
|
+
[34mℹ[39m 5 files, total: 86.39 kB
|
|
16
|
+
[32m✔[39m Build complete in [32m12102ms[39m
|
package/dist/client.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as z from "zod/v4";
|
|
2
2
|
import { OAuth2Tokens, User } from "better-auth";
|
|
3
|
-
import * as
|
|
3
|
+
import * as better_call7 from "better-call";
|
|
4
4
|
|
|
5
5
|
//#region src/types.d.ts
|
|
6
6
|
interface OIDCMapping {
|
|
@@ -216,7 +216,13 @@ interface SSOOptions {
|
|
|
216
216
|
*
|
|
217
217
|
* If you want to allow account linking for specific trusted providers, enable the `accountLinking` option in your auth config and specify those
|
|
218
218
|
* providers in the `trustedProviders` list.
|
|
219
|
+
*
|
|
219
220
|
* @default false
|
|
221
|
+
*
|
|
222
|
+
* @deprecated This option is discouraged for new projects. Relying on provider-level `email_verified` is a weaker
|
|
223
|
+
* trust signal compared to using `trustedProviders` in `accountLinking` or enabling `domainVerification` for SSO.
|
|
224
|
+
* Existing configurations will continue to work, but new integrations should use explicit trust mechanisms.
|
|
225
|
+
* This option may be removed in a future major version.
|
|
220
226
|
*/
|
|
221
227
|
trustEmailVerified?: boolean | undefined;
|
|
222
228
|
/**
|
|
@@ -240,7 +246,7 @@ interface SSOOptions {
|
|
|
240
246
|
}
|
|
241
247
|
//#endregion
|
|
242
248
|
//#region src/routes/domain-verification.d.ts
|
|
243
|
-
declare const requestDomainVerification: (options: SSOOptions) =>
|
|
249
|
+
declare const requestDomainVerification: (options: SSOOptions) => better_call7.StrictEndpoint<"/sso/request-domain-verification", {
|
|
244
250
|
method: "POST";
|
|
245
251
|
body: z.ZodObject<{
|
|
246
252
|
providerId: z.ZodString;
|
|
@@ -262,7 +268,7 @@ declare const requestDomainVerification: (options: SSOOptions) => better_call0.S
|
|
|
262
268
|
};
|
|
263
269
|
};
|
|
264
270
|
};
|
|
265
|
-
use: ((inputContext:
|
|
271
|
+
use: ((inputContext: better_call7.MiddlewareInputContext<better_call7.MiddlewareOptions>) => Promise<{
|
|
266
272
|
session: {
|
|
267
273
|
session: Record<string, any> & {
|
|
268
274
|
id: string;
|
|
@@ -290,7 +296,7 @@ declare const requestDomainVerification: (options: SSOOptions) => better_call0.S
|
|
|
290
296
|
}, {
|
|
291
297
|
domainVerificationToken: string;
|
|
292
298
|
}>;
|
|
293
|
-
declare const verifyDomain: (options: SSOOptions) =>
|
|
299
|
+
declare const verifyDomain: (options: SSOOptions) => better_call7.StrictEndpoint<"/sso/verify-domain", {
|
|
294
300
|
method: "POST";
|
|
295
301
|
body: z.ZodObject<{
|
|
296
302
|
providerId: z.ZodString;
|
|
@@ -315,7 +321,7 @@ declare const verifyDomain: (options: SSOOptions) => better_call0.StrictEndpoint
|
|
|
315
321
|
};
|
|
316
322
|
};
|
|
317
323
|
};
|
|
318
|
-
use: ((inputContext:
|
|
324
|
+
use: ((inputContext: better_call7.MiddlewareInputContext<better_call7.MiddlewareOptions>) => Promise<{
|
|
319
325
|
session: {
|
|
320
326
|
session: Record<string, any> & {
|
|
321
327
|
id: string;
|
|
@@ -343,7 +349,7 @@ declare const verifyDomain: (options: SSOOptions) => better_call0.StrictEndpoint
|
|
|
343
349
|
}, void>;
|
|
344
350
|
//#endregion
|
|
345
351
|
//#region src/routes/sso.d.ts
|
|
346
|
-
declare const spMetadata: () =>
|
|
352
|
+
declare const spMetadata: () => better_call7.StrictEndpoint<"/sso/saml2/sp/metadata", {
|
|
347
353
|
method: "GET";
|
|
348
354
|
query: z.ZodObject<{
|
|
349
355
|
providerId: z.ZodString;
|
|
@@ -367,7 +373,7 @@ declare const spMetadata: () => better_call0.StrictEndpoint<"/sso/saml2/sp/metad
|
|
|
367
373
|
} & {
|
|
368
374
|
use: any[];
|
|
369
375
|
}, Response>;
|
|
370
|
-
declare const registerSSOProvider: <O extends SSOOptions>(options: O) =>
|
|
376
|
+
declare const registerSSOProvider: <O extends SSOOptions>(options: O) => better_call7.StrictEndpoint<"/sso/register", {
|
|
371
377
|
method: "POST";
|
|
372
378
|
body: z.ZodObject<{
|
|
373
379
|
providerId: z.ZodString;
|
|
@@ -445,7 +451,7 @@ declare const registerSSOProvider: <O extends SSOOptions>(options: O) => better_
|
|
|
445
451
|
organizationId: z.ZodOptional<z.ZodString>;
|
|
446
452
|
overrideUserInfo: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
|
|
447
453
|
}, z.core.$strip>;
|
|
448
|
-
use: ((inputContext:
|
|
454
|
+
use: ((inputContext: better_call7.MiddlewareInputContext<better_call7.MiddlewareOptions>) => Promise<{
|
|
449
455
|
session: {
|
|
450
456
|
session: Record<string, any> & {
|
|
451
457
|
id: string;
|
|
@@ -637,7 +643,7 @@ declare const registerSSOProvider: <O extends SSOOptions>(options: O) => better_
|
|
|
637
643
|
domainVerified: boolean;
|
|
638
644
|
domainVerificationToken: string;
|
|
639
645
|
} & SSOProvider<O> : SSOProvider<O>>;
|
|
640
|
-
declare const signInSSO: (options?: SSOOptions) =>
|
|
646
|
+
declare const signInSSO: (options?: SSOOptions) => better_call7.StrictEndpoint<"/sign-in/sso", {
|
|
641
647
|
method: "POST";
|
|
642
648
|
body: z.ZodObject<{
|
|
643
649
|
email: z.ZodOptional<z.ZodString>;
|
|
@@ -733,7 +739,7 @@ declare const signInSSO: (options?: SSOOptions) => better_call0.StrictEndpoint<"
|
|
|
733
739
|
url: string;
|
|
734
740
|
redirect: boolean;
|
|
735
741
|
}>;
|
|
736
|
-
declare const callbackSSO: (options?: SSOOptions) =>
|
|
742
|
+
declare const callbackSSO: (options?: SSOOptions) => better_call7.StrictEndpoint<"/sso/callback/:providerId", {
|
|
737
743
|
method: "GET";
|
|
738
744
|
query: z.ZodObject<{
|
|
739
745
|
code: z.ZodOptional<z.ZodString>;
|
|
@@ -758,7 +764,7 @@ declare const callbackSSO: (options?: SSOOptions) => better_call0.StrictEndpoint
|
|
|
758
764
|
} & {
|
|
759
765
|
use: any[];
|
|
760
766
|
}, never>;
|
|
761
|
-
declare const callbackSSOSAML: (options?: SSOOptions) =>
|
|
767
|
+
declare const callbackSSOSAML: (options?: SSOOptions) => better_call7.StrictEndpoint<"/sso/saml2/callback/:providerId", {
|
|
762
768
|
method: "POST";
|
|
763
769
|
body: z.ZodObject<{
|
|
764
770
|
SAMLResponse: z.ZodString;
|
|
@@ -787,7 +793,7 @@ declare const callbackSSOSAML: (options?: SSOOptions) => better_call0.StrictEndp
|
|
|
787
793
|
} & {
|
|
788
794
|
use: any[];
|
|
789
795
|
}, never>;
|
|
790
|
-
declare const acsEndpoint: (options?: SSOOptions) =>
|
|
796
|
+
declare const acsEndpoint: (options?: SSOOptions) => better_call7.StrictEndpoint<"/sso/saml2/sp/acs/:providerId", {
|
|
791
797
|
method: "POST";
|
|
792
798
|
params: z.ZodObject<{
|
|
793
799
|
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-
|
|
1
|
+
import { a as SSOOptions, i as SAMLConfig, n as sso, o as SSOProvider, r as OIDCConfig, t as SSOPlugin } from "./index-BWvN4yrs.mjs";
|
|
2
2
|
export { OIDCConfig, SAMLConfig, SSOOptions, SSOPlugin, SSOProvider, sso };
|
package/dist/index.mjs
CHANGED
|
@@ -810,7 +810,7 @@ const callbackSSO = (options) => {
|
|
|
810
810
|
}
|
|
811
811
|
}
|
|
812
812
|
}, async (ctx) => {
|
|
813
|
-
const { code,
|
|
813
|
+
const { code, error, error_description } = ctx.query;
|
|
814
814
|
const stateData = await parseState(ctx);
|
|
815
815
|
if (!stateData) {
|
|
816
816
|
const errorURL$1 = ctx.context.options.onAPIError?.errorURL || `${ctx.context.baseURL}/error`;
|
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.
|
|
4
|
+
"version": "1.4.7-beta.2",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.mjs",
|
|
7
7
|
"types": "dist/index.d.mts",
|
|
@@ -65,16 +65,17 @@
|
|
|
65
65
|
"body-parser": "^2.2.1",
|
|
66
66
|
"express": "^5.1.0",
|
|
67
67
|
"oauth2-mock-server": "^8.2.0",
|
|
68
|
-
"tsdown": "^0.17.
|
|
69
|
-
"better-auth": "1.4.
|
|
68
|
+
"tsdown": "^0.17.2",
|
|
69
|
+
"better-auth": "1.4.7-beta.2"
|
|
70
70
|
},
|
|
71
71
|
"peerDependencies": {
|
|
72
|
-
"better-auth": "1.4.
|
|
72
|
+
"better-auth": "1.4.7-beta.2"
|
|
73
73
|
},
|
|
74
74
|
"scripts": {
|
|
75
75
|
"test": "vitest",
|
|
76
76
|
"coverage": "vitest run --coverage",
|
|
77
77
|
"lint:package": "publint run --strict",
|
|
78
|
+
"lint:types": "attw --profile esm-only --pack .",
|
|
78
79
|
"build": "tsdown",
|
|
79
80
|
"dev": "tsdown --watch",
|
|
80
81
|
"typecheck": "tsc --project tsconfig.json"
|
package/src/routes/sso.ts
CHANGED
|
@@ -1107,7 +1107,7 @@ export const callbackSSO = (options?: SSOOptions) => {
|
|
|
1107
1107
|
},
|
|
1108
1108
|
},
|
|
1109
1109
|
async (ctx) => {
|
|
1110
|
-
const { code,
|
|
1110
|
+
const { code, error, error_description } = ctx.query;
|
|
1111
1111
|
const stateData = await parseState(ctx);
|
|
1112
1112
|
if (!stateData) {
|
|
1113
1113
|
const errorURL =
|
package/src/saml.test.ts
CHANGED
|
@@ -448,13 +448,9 @@ const createMockSAMLIdP = (port: number) => {
|
|
|
448
448
|
async (req: ExpressRequest, res: ExpressResponse) => {
|
|
449
449
|
const { SAMLResponse, RelayState } = req.body;
|
|
450
450
|
try {
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
{ body: { SAMLResponse } },
|
|
455
|
-
);
|
|
456
|
-
|
|
457
|
-
const { attributes, nameID } = parseResult.extract;
|
|
451
|
+
await sp.parseLoginResponse(idp, saml.Constants.wording.binding.post, {
|
|
452
|
+
body: { SAMLResponse },
|
|
453
|
+
});
|
|
458
454
|
|
|
459
455
|
res.redirect(302, RelayState || "http://localhost:3000/dashboard");
|
|
460
456
|
} catch (error) {
|
|
@@ -550,18 +546,6 @@ describe("SAML SSO with defaultSSO array", async () => {
|
|
|
550
546
|
plugins: [sso(ssoOptions)],
|
|
551
547
|
});
|
|
552
548
|
|
|
553
|
-
const ctx = await auth.$context;
|
|
554
|
-
|
|
555
|
-
const authClient = createAuthClient({
|
|
556
|
-
baseURL: "http://localhost:3000",
|
|
557
|
-
plugins: [bearer(), ssoClient()],
|
|
558
|
-
fetchOptions: {
|
|
559
|
-
customFetchImpl: async (url, init) => {
|
|
560
|
-
return auth.handler(new Request(url, init));
|
|
561
|
-
},
|
|
562
|
-
},
|
|
563
|
-
});
|
|
564
|
-
|
|
565
549
|
beforeAll(async () => {
|
|
566
550
|
await mockIdP.start();
|
|
567
551
|
});
|
|
@@ -619,8 +603,6 @@ describe("SAML SSO", async () => {
|
|
|
619
603
|
plugins: [sso(ssoOptions)],
|
|
620
604
|
});
|
|
621
605
|
|
|
622
|
-
const ctx = await auth.$context;
|
|
623
|
-
|
|
624
606
|
const authClient = createAuthClient({
|
|
625
607
|
baseURL: "http://localhost:3000",
|
|
626
608
|
plugins: [bearer(), ssoClient()],
|
|
@@ -639,7 +621,7 @@ describe("SAML SSO", async () => {
|
|
|
639
621
|
|
|
640
622
|
beforeAll(async () => {
|
|
641
623
|
await mockIdP.start();
|
|
642
|
-
|
|
624
|
+
await authClient.signUp.email({
|
|
643
625
|
email: testUser.email,
|
|
644
626
|
password: testUser.password,
|
|
645
627
|
name: testUser.name,
|
|
@@ -667,7 +649,7 @@ describe("SAML SSO", async () => {
|
|
|
667
649
|
password: testUser.password,
|
|
668
650
|
name: testUser.name,
|
|
669
651
|
});
|
|
670
|
-
|
|
652
|
+
await authClient.signIn.email(testUser, {
|
|
671
653
|
throw: true,
|
|
672
654
|
onSuccess: setCookieToHeader(headers),
|
|
673
655
|
});
|
|
@@ -676,7 +658,7 @@ describe("SAML SSO", async () => {
|
|
|
676
658
|
|
|
677
659
|
it("should register a new SAML provider", async () => {
|
|
678
660
|
const headers = await getAuthHeaders();
|
|
679
|
-
|
|
661
|
+
await authClient.signIn.email(testUser, {
|
|
680
662
|
throw: true,
|
|
681
663
|
onSuccess: setCookieToHeader(headers),
|
|
682
664
|
});
|
|
@@ -847,11 +829,11 @@ describe("SAML SSO", async () => {
|
|
|
847
829
|
});
|
|
848
830
|
it("should initiate SAML login and handle response", async () => {
|
|
849
831
|
const headers = await getAuthHeaders();
|
|
850
|
-
|
|
832
|
+
await authClient.signIn.email(testUser, {
|
|
851
833
|
throw: true,
|
|
852
834
|
onSuccess: setCookieToHeader(headers),
|
|
853
835
|
});
|
|
854
|
-
|
|
836
|
+
await auth.api.registerSSOProvider({
|
|
855
837
|
body: {
|
|
856
838
|
providerId: "saml-provider-1",
|
|
857
839
|
issuer: "http://localhost:8081",
|
|
@@ -1184,11 +1166,7 @@ describe("SAML SSO", async () => {
|
|
|
1184
1166
|
});
|
|
1185
1167
|
|
|
1186
1168
|
it("should deny account linking when provider is not trusted and domain is not verified", async () => {
|
|
1187
|
-
const {
|
|
1188
|
-
auth: authUntrusted,
|
|
1189
|
-
signInWithTestUser,
|
|
1190
|
-
client,
|
|
1191
|
-
} = await getTestInstance({
|
|
1169
|
+
const { auth: authUntrusted, signInWithTestUser } = await getTestInstance({
|
|
1192
1170
|
account: {
|
|
1193
1171
|
accountLinking: {
|
|
1194
1172
|
enabled: true,
|
|
@@ -1401,7 +1379,7 @@ describe("SAML SSO with custom fields", () => {
|
|
|
1401
1379
|
|
|
1402
1380
|
beforeAll(async () => {
|
|
1403
1381
|
await mockIdP.start();
|
|
1404
|
-
|
|
1382
|
+
await authClient.signUp.email({
|
|
1405
1383
|
email: testUser.email,
|
|
1406
1384
|
password: testUser.password,
|
|
1407
1385
|
name: testUser.name,
|
package/src/types.ts
CHANGED
|
@@ -232,7 +232,13 @@ export interface SSOOptions {
|
|
|
232
232
|
*
|
|
233
233
|
* If you want to allow account linking for specific trusted providers, enable the `accountLinking` option in your auth config and specify those
|
|
234
234
|
* providers in the `trustedProviders` list.
|
|
235
|
+
*
|
|
235
236
|
* @default false
|
|
237
|
+
*
|
|
238
|
+
* @deprecated This option is discouraged for new projects. Relying on provider-level `email_verified` is a weaker
|
|
239
|
+
* trust signal compared to using `trustedProviders` in `accountLinking` or enabling `domainVerification` for SSO.
|
|
240
|
+
* Existing configurations will continue to work, but new integrations should use explicit trust mechanisms.
|
|
241
|
+
* This option may be removed in a future major version.
|
|
236
242
|
*/
|
|
237
243
|
trustEmailVerified?: boolean | undefined;
|
|
238
244
|
/**
|