@better-auth/sso 1.4.0-beta.20 → 1.4.0-beta.21
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 +7 -8
- package/dist/client.d.mts +1 -1
- package/dist/client.mjs +0 -2
- package/dist/{index-Ba2niv2R.d.mts → index-C091fIpa.d.mts} +7 -1
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +1222 -1
- package/package.json +3 -3
- package/src/client.ts +1 -1
- package/src/index.ts +2 -2
- package/src/routes/sso.ts +14 -0
- package/src/saml.test.ts +64 -0
- package/dist/src-BUIX9n33.mjs +0 -1215
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.0-beta.
|
|
4
|
+
"version": "1.4.0-beta.21",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.mjs",
|
|
7
7
|
"homepage": "https://www.better-auth.com/docs/plugins/sso",
|
|
@@ -65,10 +65,10 @@
|
|
|
65
65
|
"express": "^5.1.0",
|
|
66
66
|
"oauth2-mock-server": "^7.2.1",
|
|
67
67
|
"tsdown": "^0.16.0",
|
|
68
|
-
"better-auth": "1.4.0-beta.
|
|
68
|
+
"better-auth": "1.4.0-beta.21"
|
|
69
69
|
},
|
|
70
70
|
"peerDependencies": {
|
|
71
|
-
"better-auth": "1.4.0-beta.
|
|
71
|
+
"better-auth": "1.4.0-beta.21"
|
|
72
72
|
},
|
|
73
73
|
"scripts": {
|
|
74
74
|
"test": "vitest",
|
package/src/client.ts
CHANGED
package/src/index.ts
CHANGED
|
@@ -9,9 +9,9 @@ import {
|
|
|
9
9
|
signInSSO,
|
|
10
10
|
spMetadata,
|
|
11
11
|
} from "./routes/sso";
|
|
12
|
-
import type { OIDCConfig, SAMLConfig, SSOOptions } from "./types";
|
|
12
|
+
import type { OIDCConfig, SAMLConfig, SSOOptions, SSOProvider } from "./types";
|
|
13
13
|
|
|
14
|
-
export type { SAMLConfig, OIDCConfig, SSOOptions };
|
|
14
|
+
export type { SAMLConfig, OIDCConfig, SSOOptions, SSOProvider };
|
|
15
15
|
|
|
16
16
|
const fastValidator = {
|
|
17
17
|
async validate(xml: string) {
|
package/src/routes/sso.ts
CHANGED
|
@@ -63,6 +63,7 @@ export const spMetadata = () => {
|
|
|
63
63
|
}),
|
|
64
64
|
metadata: {
|
|
65
65
|
openapi: {
|
|
66
|
+
operationId: "getSSOServiceProviderMetadata",
|
|
66
67
|
summary: "Get Service Provider metadata",
|
|
67
68
|
description: "Returns the SAML metadata for the Service Provider",
|
|
68
69
|
responses: {
|
|
@@ -337,6 +338,7 @@ export const registerSSOProvider = (options?: SSOOptions) => {
|
|
|
337
338
|
use: [sessionMiddleware],
|
|
338
339
|
metadata: {
|
|
339
340
|
openapi: {
|
|
341
|
+
operationId: "registerSSOProvider",
|
|
340
342
|
summary: "Register an OIDC provider",
|
|
341
343
|
description:
|
|
342
344
|
"This endpoint is used to register an OIDC provider. This is used to configure the provider and link it to an organization",
|
|
@@ -726,6 +728,7 @@ export const signInSSO = (options?: SSOOptions) => {
|
|
|
726
728
|
}),
|
|
727
729
|
metadata: {
|
|
728
730
|
openapi: {
|
|
731
|
+
operationId: "signInWithSSO",
|
|
729
732
|
summary: "Sign in with SSO provider",
|
|
730
733
|
description:
|
|
731
734
|
"This endpoint is used to sign in with an SSO provider. It redirects to the provider's authorization URL",
|
|
@@ -1014,6 +1017,7 @@ export const callbackSSO = (options?: SSOOptions) => {
|
|
|
1014
1017
|
metadata: {
|
|
1015
1018
|
isAction: false,
|
|
1016
1019
|
openapi: {
|
|
1020
|
+
operationId: "handleSSOCallback",
|
|
1017
1021
|
summary: "Callback URL for SSO provider",
|
|
1018
1022
|
description:
|
|
1019
1023
|
"This endpoint is used as the callback URL for SSO providers. It handles the authorization code and exchanges it for an access token",
|
|
@@ -1362,6 +1366,7 @@ export const callbackSSOSAML = (options?: SSOOptions) => {
|
|
|
1362
1366
|
metadata: {
|
|
1363
1367
|
isAction: false,
|
|
1364
1368
|
openapi: {
|
|
1369
|
+
operationId: "handleSAMLCallback",
|
|
1365
1370
|
summary: "Callback URL for SAML provider",
|
|
1366
1371
|
description:
|
|
1367
1372
|
"This endpoint is used as the callback URL for SAML providers.",
|
|
@@ -1584,6 +1589,14 @@ export const callbackSSOSAML = (options?: SSOOptions) => {
|
|
|
1584
1589
|
if (existingUser) {
|
|
1585
1590
|
user = existingUser;
|
|
1586
1591
|
} else {
|
|
1592
|
+
// if implicit sign up is disabled, we should not create a new user nor a new account.
|
|
1593
|
+
if (options?.disableImplicitSignUp) {
|
|
1594
|
+
throw new APIError("UNAUTHORIZED", {
|
|
1595
|
+
message:
|
|
1596
|
+
"User not found and implicit sign up is disabled for this provider",
|
|
1597
|
+
});
|
|
1598
|
+
}
|
|
1599
|
+
|
|
1587
1600
|
user = await ctx.context.internalAdapter.createUser({
|
|
1588
1601
|
email: userInfo.email,
|
|
1589
1602
|
name: userInfo.name,
|
|
@@ -1687,6 +1700,7 @@ export const acsEndpoint = (options?: SSOOptions) => {
|
|
|
1687
1700
|
metadata: {
|
|
1688
1701
|
isAction: false,
|
|
1689
1702
|
openapi: {
|
|
1703
|
+
operationId: "handleSAMLAssertionConsumerService",
|
|
1690
1704
|
summary: "SAML Assertion Consumer Service",
|
|
1691
1705
|
description:
|
|
1692
1706
|
"Handles SAML responses from IdP after successful authentication",
|
package/src/saml.test.ts
CHANGED
|
@@ -1118,4 +1118,68 @@ describe("SAML SSO", async () => {
|
|
|
1118
1118
|
},
|
|
1119
1119
|
});
|
|
1120
1120
|
});
|
|
1121
|
+
|
|
1122
|
+
it("should reject SAML sign-in when disableImplicitSignUp is true and user doesn't exist", async () => {
|
|
1123
|
+
const { auth: authWithDisabledSignUp, signInWithTestUser } =
|
|
1124
|
+
await getTestInstance({
|
|
1125
|
+
plugins: [sso({ disableImplicitSignUp: true })],
|
|
1126
|
+
});
|
|
1127
|
+
|
|
1128
|
+
const { headers } = await signInWithTestUser();
|
|
1129
|
+
|
|
1130
|
+
// Register SAML provider
|
|
1131
|
+
await authWithDisabledSignUp.api.registerSSOProvider({
|
|
1132
|
+
body: {
|
|
1133
|
+
providerId: "saml-test-provider",
|
|
1134
|
+
issuer: "http://localhost:8081",
|
|
1135
|
+
domain: "http://localhost:8081",
|
|
1136
|
+
samlConfig: {
|
|
1137
|
+
entryPoint: "http://localhost:8081/api/sso/saml2/idp/post",
|
|
1138
|
+
cert: certificate,
|
|
1139
|
+
callbackUrl: "http://localhost:3000/dashboard",
|
|
1140
|
+
wantAssertionsSigned: false,
|
|
1141
|
+
signatureAlgorithm: "sha256",
|
|
1142
|
+
digestAlgorithm: "sha256",
|
|
1143
|
+
idpMetadata: {
|
|
1144
|
+
metadata: idpMetadata,
|
|
1145
|
+
},
|
|
1146
|
+
spMetadata: {
|
|
1147
|
+
metadata: spMetadata,
|
|
1148
|
+
},
|
|
1149
|
+
identifierFormat:
|
|
1150
|
+
"urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress",
|
|
1151
|
+
},
|
|
1152
|
+
},
|
|
1153
|
+
headers: headers,
|
|
1154
|
+
});
|
|
1155
|
+
|
|
1156
|
+
// Identity Provider-initiated: Get SAML response directly from IdP
|
|
1157
|
+
// The mock IdP will return test@email.com, which doesn't exist in the DB
|
|
1158
|
+
let samlResponse: any;
|
|
1159
|
+
await betterFetch("http://localhost:8081/api/sso/saml2/idp/post", {
|
|
1160
|
+
onSuccess: async (context) => {
|
|
1161
|
+
samlResponse = await context.data;
|
|
1162
|
+
},
|
|
1163
|
+
});
|
|
1164
|
+
|
|
1165
|
+
// Attempt to complete SAML callback - should fail because test@email.com doesn't exist
|
|
1166
|
+
// and disableImplicitSignUp is true
|
|
1167
|
+
await expect(
|
|
1168
|
+
authWithDisabledSignUp.api.callbackSSOSAML({
|
|
1169
|
+
body: {
|
|
1170
|
+
SAMLResponse: samlResponse.samlResponse,
|
|
1171
|
+
RelayState: "http://localhost:3000/dashboard",
|
|
1172
|
+
},
|
|
1173
|
+
params: {
|
|
1174
|
+
providerId: "saml-test-provider",
|
|
1175
|
+
},
|
|
1176
|
+
}),
|
|
1177
|
+
).rejects.toMatchObject({
|
|
1178
|
+
status: "UNAUTHORIZED",
|
|
1179
|
+
body: {
|
|
1180
|
+
message:
|
|
1181
|
+
"User not found and implicit sign up is disabled for this provider",
|
|
1182
|
+
},
|
|
1183
|
+
});
|
|
1184
|
+
});
|
|
1121
1185
|
});
|