@better-auth/sso 1.7.20 → 1.7.22
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/dist/client.d.mts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { t as SSOPlugin } from "./index-
|
|
1
|
+
import { t as SSOPlugin } from "./index-CndkJEsk.mjs";
|
|
2
2
|
import { DBFieldAttribute } from "better-auth/db";
|
|
3
|
-
//#region src/client.d.ts
|
|
4
3
|
interface SSOClientOptions {
|
|
5
4
|
domainVerification?: {
|
|
6
5
|
enabled: boolean;
|
|
@@ -29,5 +28,4 @@ export declare const ssoClient: <CO extends SSOClientOptions>(options?: CO | und
|
|
|
29
28
|
"/sso/get-provider": "GET";
|
|
30
29
|
};
|
|
31
30
|
};
|
|
32
|
-
//#endregion
|
|
33
31
|
export {};
|
package/dist/client.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { t as PACKAGE_VERSION } from "./version-
|
|
2
|
-
|
|
1
|
+
import { t as PACKAGE_VERSION } from "./version-DnGxDgB4.mjs";
|
|
2
|
+
// src/client.ts
|
|
3
3
|
const ssoClient = (options) => {
|
|
4
4
|
return {
|
|
5
5
|
id: "sso-client",
|
|
@@ -11,5 +11,4 @@ const ssoClient = (options) => {
|
|
|
11
11
|
}
|
|
12
12
|
};
|
|
13
13
|
};
|
|
14
|
-
//#endregion
|
|
15
14
|
export { ssoClient };
|
|
@@ -6,7 +6,6 @@ import { DBFieldAttribute, FieldAttributeToObject, InferAdditionalFieldsFromPlug
|
|
|
6
6
|
import { Awaitable, DBTransactionAdapter, OAuth2Tokens, User } from "better-auth";
|
|
7
7
|
import "@better-auth/core/db/adapter";
|
|
8
8
|
import "@better-auth/core";
|
|
9
|
-
//#region src/saml/algorithms.d.ts
|
|
10
9
|
declare const SignatureAlgorithm: {
|
|
11
10
|
readonly RSA_SHA1: "http://www.w3.org/2000/09/xmldsig#rsa-sha1";
|
|
12
11
|
readonly RSA_SHA256: "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";
|
|
@@ -44,8 +43,6 @@ interface AlgorithmValidationOptions {
|
|
|
44
43
|
allowedKeyEncryptionAlgorithms?: string[];
|
|
45
44
|
allowedDataEncryptionAlgorithms?: string[];
|
|
46
45
|
}
|
|
47
|
-
//#endregion
|
|
48
|
-
//#region src/types.d.ts
|
|
49
46
|
interface OIDCMapping {
|
|
50
47
|
email?: string | undefined;
|
|
51
48
|
emailVerified?: string | undefined;
|
|
@@ -683,8 +680,6 @@ interface SSOOptions {
|
|
|
683
680
|
idpInitiatedCallbackUrl?: string | undefined;
|
|
684
681
|
};
|
|
685
682
|
}
|
|
686
|
-
//#endregion
|
|
687
|
-
//#region src/routes/domain-verification.d.ts
|
|
688
683
|
declare const requestDomainVerification: (options: SSOOptions) => import("better-call").StrictEndpoint<"/sso/request-domain-verification", {
|
|
689
684
|
method: "POST";
|
|
690
685
|
body: z.ZodObject<{
|
|
@@ -782,16 +777,12 @@ declare const verifyDomain: (options: SSOOptions) => import("better-call").Stric
|
|
|
782
777
|
};
|
|
783
778
|
}>>[];
|
|
784
779
|
}, void>;
|
|
785
|
-
//#endregion
|
|
786
|
-
//#region src/utils.d.ts
|
|
787
780
|
declare function parseCertificate(certPem: string): {
|
|
788
781
|
fingerprintSha256: string;
|
|
789
782
|
notBefore: string;
|
|
790
783
|
notAfter: string;
|
|
791
784
|
publicKeyAlgorithm: string;
|
|
792
785
|
};
|
|
793
|
-
//#endregion
|
|
794
|
-
//#region src/routes/providers.d.ts
|
|
795
786
|
type ParsedCert = ReturnType<typeof parseCertificate>;
|
|
796
787
|
type SanitizedCert = ParsedCert | {
|
|
797
788
|
error: string;
|
|
@@ -1150,8 +1141,6 @@ declare const deleteSSOProvider: (options?: SSOOptions) => import("better-call")
|
|
|
1150
1141
|
}, {
|
|
1151
1142
|
success: boolean;
|
|
1152
1143
|
}>;
|
|
1153
|
-
//#endregion
|
|
1154
|
-
//#region src/routes/sso.d.ts
|
|
1155
1144
|
declare const spMetadata: (options?: SSOOptions) => import("better-call").StrictEndpoint<"/sso/saml2/sp/metadata", {
|
|
1156
1145
|
method: "GET";
|
|
1157
1146
|
query: z.ZodObject<{
|
|
@@ -1200,7 +1189,9 @@ declare const registerSSOProvider: <O extends SSOOptions>(options: O) => import(
|
|
|
1200
1189
|
}>>[];
|
|
1201
1190
|
metadata: {
|
|
1202
1191
|
$Infer: {
|
|
1203
|
-
body:
|
|
1192
|
+
body: {
|
|
1193
|
+
[x: string]: any;
|
|
1194
|
+
} & SSOProviderAdditionalFieldsInput<O>;
|
|
1204
1195
|
};
|
|
1205
1196
|
openapi: {
|
|
1206
1197
|
operationId: string;
|
|
@@ -1627,8 +1618,6 @@ declare const initiateSLO: (options?: SSOOptions) => import("better-call").Stric
|
|
|
1627
1618
|
readonly scope: "server";
|
|
1628
1619
|
};
|
|
1629
1620
|
}, never>;
|
|
1630
|
-
//#endregion
|
|
1631
|
-
//#region src/constants.d.ts
|
|
1632
1621
|
/**
|
|
1633
1622
|
* Default clock skew tolerance (5 minutes).
|
|
1634
1623
|
* Allows for minor time differences between IdP and SP servers.
|
|
@@ -1649,8 +1638,6 @@ declare const DEFAULT_MAX_SAML_RESPONSE_SIZE: number;
|
|
|
1649
1638
|
* Protects against oversized metadata documents.
|
|
1650
1639
|
*/
|
|
1651
1640
|
declare const DEFAULT_MAX_SAML_METADATA_SIZE: number;
|
|
1652
|
-
//#endregion
|
|
1653
|
-
//#region src/routes/helpers.d.ts
|
|
1654
1641
|
interface SAMLServiceProviderPolicy {
|
|
1655
1642
|
/** Effective assertion-signing requirement advertised by SP metadata. */
|
|
1656
1643
|
wantAssertionsSigned: boolean;
|
|
@@ -1668,8 +1655,6 @@ declare function deriveSAMLServiceProviderPolicy(config: Pick<SAMLConfig, "spMet
|
|
|
1668
1655
|
* parsing and manual-configuration validation as SAML authentication.
|
|
1669
1656
|
*/
|
|
1670
1657
|
declare function deriveSAMLIdentityProviderEntityID(config: SAMLConfig): string;
|
|
1671
|
-
//#endregion
|
|
1672
|
-
//#region src/saml/timestamp.d.ts
|
|
1673
1658
|
interface TimestampValidationOptions {
|
|
1674
1659
|
clockSkew?: number;
|
|
1675
1660
|
requireTimestamps?: boolean;
|
|
@@ -1688,8 +1673,6 @@ interface SAMLConditions {
|
|
|
1688
1673
|
* @throws {APIError} If timestamps are invalid, expired, or not yet valid
|
|
1689
1674
|
*/
|
|
1690
1675
|
declare function validateSAMLTimestamp(conditions: SAMLConditions | undefined, options?: TimestampValidationOptions): void;
|
|
1691
|
-
//#endregion
|
|
1692
|
-
//#region src/oidc/types.d.ts
|
|
1693
1676
|
/**
|
|
1694
1677
|
* OIDC Discovery Types
|
|
1695
1678
|
*
|
|
@@ -1856,8 +1839,6 @@ interface DiscoverOIDCConfigParams {
|
|
|
1856
1839
|
*/
|
|
1857
1840
|
declare const REQUIRED_DISCOVERY_FIELDS: readonly ["issuer", "authorization_endpoint", "token_endpoint", "jwks_uri"];
|
|
1858
1841
|
type RequiredDiscoveryField = (typeof REQUIRED_DISCOVERY_FIELDS)[number];
|
|
1859
|
-
//#endregion
|
|
1860
|
-
//#region src/oidc/discovery.d.ts
|
|
1861
1842
|
/**
|
|
1862
1843
|
* Main entry point: Discover and hydrate OIDC configuration from an issuer.
|
|
1863
1844
|
*
|
|
@@ -1957,8 +1938,6 @@ declare function selectTokenEndpointAuthMethod(doc: OIDCDiscoveryDocument, exist
|
|
|
1957
1938
|
* @returns true if runtime discovery should be performed
|
|
1958
1939
|
*/
|
|
1959
1940
|
declare function needsRuntimeDiscovery(config: Partial<HydratedOIDCConfig> | undefined): boolean;
|
|
1960
|
-
//#endregion
|
|
1961
|
-
//#region src/index.d.ts
|
|
1962
1941
|
declare module "@better-auth/core" {
|
|
1963
1942
|
interface BetterAuthPluginRegistry<AuthOptions, Options> {
|
|
1964
1943
|
sso: {
|
|
@@ -2022,5 +2001,4 @@ declare function sso<O extends SSOOptions>(options?: O | undefined): {
|
|
|
2022
2001
|
};
|
|
2023
2002
|
options: NoInfer<O>;
|
|
2024
2003
|
};
|
|
2025
|
-
//#endregion
|
|
2026
2004
|
export { SAMLIdentityProviderMetadata as A, SSOUserResolutionContext as B, deriveSAMLIdentityProviderEntityID as C, DEFAULT_MAX_SAML_RESPONSE_SIZE as D, DEFAULT_MAX_SAML_METADATA_SIZE as E, SSOProviderMutationGuardInput as F, DigestAlgorithm as G, AlgorithmValidationOptions as H, SSOProviderReference as I, KeyEncryptionAlgorithm as K, SSOProviderUserProfile as L, SSOOptions as M, SSOProvider as N, OIDCConfig as O, SSOProviderMutationGuardContext as P, SSOSAMLUserResolutionInput as R, SAMLServiceProviderPolicy as S, DEFAULT_CLOCK_SKEW_MS as T, DataEncryptionAlgorithm as U, SSOUserResolutionInput as V, DeprecatedAlgorithmBehavior as W, REQUIRED_DISCOVERY_FIELDS as _, fetchDiscoveryDocument as a, TimestampValidationOptions as b, normalizeUrl as c, validateDiscoveryUrl as d, DiscoverOIDCConfigParams as f, OIDCDiscoveryDocument as g, HydratedOIDCConfig as h, discoverOIDCConfig as i, SSOOIDCUserResolutionInput as j, SAMLConfig as k, selectTokenEndpointAuthMethod as l, DiscoveryErrorCode as m, sso as n, needsRuntimeDiscovery as o, DiscoveryError as p, SignatureAlgorithm as q, computeDiscoveryUrl as r, normalizeDiscoveryUrls as s, SSOPlugin as t, validateDiscoveryDocument as u, RequiredDiscoveryField as v, deriveSAMLServiceProviderPolicy as w, validateSAMLTimestamp as x, SAMLConditions as y, SSOUserResolution as z };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { A as SAMLIdentityProviderMetadata, B as SSOUserResolutionContext, C as deriveSAMLIdentityProviderEntityID, D as DEFAULT_MAX_SAML_RESPONSE_SIZE, E as DEFAULT_MAX_SAML_METADATA_SIZE, F as SSOProviderMutationGuardInput, G as DigestAlgorithm, H as AlgorithmValidationOptions, I as SSOProviderReference, K as KeyEncryptionAlgorithm, L as SSOProviderUserProfile, M as SSOOptions, N as SSOProvider, O as OIDCConfig, P as SSOProviderMutationGuardContext, R as SSOSAMLUserResolutionInput, S as SAMLServiceProviderPolicy, T as DEFAULT_CLOCK_SKEW_MS, U as DataEncryptionAlgorithm, V as SSOUserResolutionInput, W as DeprecatedAlgorithmBehavior, _ as REQUIRED_DISCOVERY_FIELDS, a as fetchDiscoveryDocument, b as TimestampValidationOptions, c as normalizeUrl, d as validateDiscoveryUrl, f as DiscoverOIDCConfigParams, g as OIDCDiscoveryDocument, h as HydratedOIDCConfig, i as discoverOIDCConfig, j as SSOOIDCUserResolutionInput, k as SAMLConfig, l as selectTokenEndpointAuthMethod, m as DiscoveryErrorCode, n as sso, o as needsRuntimeDiscovery, p as DiscoveryError, q as SignatureAlgorithm, r as computeDiscoveryUrl, s as normalizeDiscoveryUrls, t as SSOPlugin, u as validateDiscoveryDocument, v as RequiredDiscoveryField, w as deriveSAMLServiceProviderPolicy, x as validateSAMLTimestamp, y as SAMLConditions, z as SSOUserResolution } from "./index-
|
|
1
|
+
import { A as SAMLIdentityProviderMetadata, B as SSOUserResolutionContext, C as deriveSAMLIdentityProviderEntityID, D as DEFAULT_MAX_SAML_RESPONSE_SIZE, E as DEFAULT_MAX_SAML_METADATA_SIZE, F as SSOProviderMutationGuardInput, G as DigestAlgorithm, H as AlgorithmValidationOptions, I as SSOProviderReference, K as KeyEncryptionAlgorithm, L as SSOProviderUserProfile, M as SSOOptions, N as SSOProvider, O as OIDCConfig, P as SSOProviderMutationGuardContext, R as SSOSAMLUserResolutionInput, S as SAMLServiceProviderPolicy, T as DEFAULT_CLOCK_SKEW_MS, U as DataEncryptionAlgorithm, V as SSOUserResolutionInput, W as DeprecatedAlgorithmBehavior, _ as REQUIRED_DISCOVERY_FIELDS, a as fetchDiscoveryDocument, b as TimestampValidationOptions, c as normalizeUrl, d as validateDiscoveryUrl, f as DiscoverOIDCConfigParams, g as OIDCDiscoveryDocument, h as HydratedOIDCConfig, i as discoverOIDCConfig, j as SSOOIDCUserResolutionInput, k as SAMLConfig, l as selectTokenEndpointAuthMethod, m as DiscoveryErrorCode, n as sso, o as needsRuntimeDiscovery, p as DiscoveryError, q as SignatureAlgorithm, r as computeDiscoveryUrl, s as normalizeDiscoveryUrls, t as SSOPlugin, u as validateDiscoveryDocument, v as RequiredDiscoveryField, w as deriveSAMLServiceProviderPolicy, x as validateSAMLTimestamp, y as SAMLConditions, z as SSOUserResolution } from "./index-CndkJEsk.mjs";
|
|
2
2
|
export { type AlgorithmValidationOptions, DEFAULT_CLOCK_SKEW_MS, DEFAULT_MAX_SAML_METADATA_SIZE, DEFAULT_MAX_SAML_RESPONSE_SIZE, DataEncryptionAlgorithm, type DeprecatedAlgorithmBehavior, DigestAlgorithm, type DiscoverOIDCConfigParams, DiscoveryError, type DiscoveryErrorCode, type HydratedOIDCConfig, KeyEncryptionAlgorithm, type OIDCConfig, type OIDCDiscoveryDocument, REQUIRED_DISCOVERY_FIELDS, type RequiredDiscoveryField, type SAMLConditions, type SAMLConfig, type SAMLIdentityProviderMetadata, type SAMLServiceProviderPolicy, type SSOOIDCUserResolutionInput, type SSOOptions, SSOPlugin, type SSOProvider, type SSOProviderMutationGuardContext, type SSOProviderMutationGuardInput, type SSOProviderReference, type SSOProviderUserProfile, type SSOSAMLUserResolutionInput, type SSOUserResolution, type SSOUserResolutionContext, type SSOUserResolutionInput, SignatureAlgorithm, type TimestampValidationOptions, computeDiscoveryUrl, deriveSAMLIdentityProviderEntityID, deriveSAMLServiceProviderPolicy, discoverOIDCConfig, fetchDiscoveryDocument, needsRuntimeDiscovery, normalizeDiscoveryUrls, normalizeUrl, selectTokenEndpointAuthMethod, sso, validateDiscoveryDocument, validateDiscoveryUrl, validateSAMLTimestamp };
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { t as PACKAGE_VERSION } from "./version-
|
|
2
|
-
import { APIError, addOAuthServerContext, createAuthEndpoint, createAuthMiddleware, getSessionFromCtx, sessionMiddleware } from "better-auth/api";
|
|
1
|
+
import { t as PACKAGE_VERSION } from "./version-DnGxDgB4.mjs";
|
|
2
|
+
import { APIError, addOAuthServerContext, createAuthEndpoint, createAuthMiddleware, generateGenericState, getSessionFromCtx, parseGenericState, sessionMiddleware } from "better-auth/api";
|
|
3
3
|
import { XMLParser, XMLValidator } from "fast-xml-parser";
|
|
4
4
|
import { X509Certificate } from "node:crypto";
|
|
5
5
|
import { getHostname } from "tldts";
|
|
@@ -17,12 +17,13 @@ import { DOMParser } from "@xmldom/xmldom";
|
|
|
17
17
|
import samlifyDefault, * as samlifyNamespace from "samlify";
|
|
18
18
|
import { defineErrorCodes } from "@better-auth/core/utils/error-codes";
|
|
19
19
|
import { parseInputData, toZodSchema } from "better-auth/db";
|
|
20
|
+
import { HIDE_METADATA } from "@better-auth/core/api";
|
|
21
|
+
import { PRIVATE_KEY_JWT_SIGNING_ALGORITHMS, authorizationCodeRequest, createAuthorizationURL, createPrivateKeyJwtClientAssertionGetter, getOAuth2Tokens, parseStringBoolean } from "@better-auth/core/oauth2";
|
|
20
22
|
import { isAPIError } from "@better-auth/core/utils/is-api-error";
|
|
21
23
|
import { appendQueryParams } from "@better-auth/core/utils/url";
|
|
22
|
-
import { HIDE_METADATA, PRIVATE_KEY_JWT_SIGNING_ALGORITHMS, authorizationCodeRequest, createAuthorizationURL, createPrivateKeyJwtClientAssertionGetter, generateGenericState, generateState, getOAuth2Tokens, parseGenericState, parseState } from "better-auth";
|
|
23
24
|
import { deleteSessionCookie, setAccountCookie, setSessionCookie } from "better-auth/cookies";
|
|
24
|
-
import { additionalAuthorizationParamsSchema, handleOAuthUserInfo } from "better-auth/oauth2";
|
|
25
|
-
|
|
25
|
+
import { additionalAuthorizationParamsSchema, generateState, handleOAuthUserInfo, parseState } from "better-auth/oauth2";
|
|
26
|
+
// src/constants.ts
|
|
26
27
|
/**
|
|
27
28
|
* SAML Constants
|
|
28
29
|
*
|
|
@@ -61,8 +62,7 @@ const DEFAULT_MAX_SAML_RESPONSE_SIZE = 262144;
|
|
|
61
62
|
* Protects against oversized metadata documents.
|
|
62
63
|
*/
|
|
63
64
|
const DEFAULT_MAX_SAML_METADATA_SIZE = 102400;
|
|
64
|
-
|
|
65
|
-
//#region src/utils.ts
|
|
65
|
+
// src/utils.ts
|
|
66
66
|
const unsafeSAMLRedirectPathPrefix = /^\/(?:\/|\\|%2f|%5c)/i;
|
|
67
67
|
const isSafeSAMLRedirectPath = (url) => url.startsWith("/") && !unsafeSAMLRedirectPathPrefix.test(url);
|
|
68
68
|
/**
|
|
@@ -94,16 +94,6 @@ const domainMatches = (searchDomain, domainList) => {
|
|
|
94
94
|
return domains.some((domain) => search === domain || search.endsWith(`.${domain}`));
|
|
95
95
|
};
|
|
96
96
|
/**
|
|
97
|
-
* Strictly parse a provider-supplied email-verification claim.
|
|
98
|
-
*
|
|
99
|
-
* OIDC userInfo, OIDC id-token, and SAML attribute values are frequently
|
|
100
|
-
* strings, so a loose `Boolean(value)` or truthy fallback treats the string
|
|
101
|
-
* `"false"` as verified. Only a boolean `true` or the exact string `"true"`
|
|
102
|
-
* count as verified; every other value, including `"false"`, `"0"`, `""`,
|
|
103
|
-
* numbers, arrays, and objects, is unverified.
|
|
104
|
-
*/
|
|
105
|
-
const parseProviderEmailVerified = (value) => value === true || value === "true";
|
|
106
|
-
/**
|
|
107
97
|
* Validates email domain against allowed domain(s).
|
|
108
98
|
* Supports comma-separated domains for multi-domain SSO.
|
|
109
99
|
*/
|
|
@@ -151,8 +141,7 @@ function maskClientId(clientId) {
|
|
|
151
141
|
if (clientId.length <= 4) return "****";
|
|
152
142
|
return `****${clientId.slice(-4)}`;
|
|
153
143
|
}
|
|
154
|
-
|
|
155
|
-
//#region src/linking/org-assignment.ts
|
|
144
|
+
// src/linking/org-assignment.ts
|
|
156
145
|
const VERIFIED_PROVIDER_PAGE_SIZE = 100;
|
|
157
146
|
function getEmailDomain(email) {
|
|
158
147
|
const parts = email.trim().toLowerCase().split("@");
|
|
@@ -295,8 +284,7 @@ async function assignOrganizationByDomain(ctx, options) {
|
|
|
295
284
|
...options
|
|
296
285
|
});
|
|
297
286
|
}
|
|
298
|
-
|
|
299
|
-
//#region src/oidc/types.ts
|
|
287
|
+
// src/oidc/types.ts
|
|
300
288
|
/**
|
|
301
289
|
* Custom error class for OIDC discovery failures.
|
|
302
290
|
* Can be caught and mapped to APIError at the edge.
|
|
@@ -321,8 +309,7 @@ const REQUIRED_DISCOVERY_FIELDS = [
|
|
|
321
309
|
"token_endpoint",
|
|
322
310
|
"jwks_uri"
|
|
323
311
|
];
|
|
324
|
-
|
|
325
|
-
//#region src/oidc/discovery.ts
|
|
312
|
+
// src/oidc/discovery.ts
|
|
326
313
|
/**
|
|
327
314
|
* OIDC Discovery Pipeline
|
|
328
315
|
*
|
|
@@ -788,8 +775,7 @@ async function ensureRuntimeDiscovery(config, issuer, isTrustedOrigin) {
|
|
|
788
775
|
await assertServerFetchedOIDCEndpointsAllowed(resolved, isTrustedOrigin);
|
|
789
776
|
return resolved;
|
|
790
777
|
}
|
|
791
|
-
|
|
792
|
-
//#region src/oidc/errors.ts
|
|
778
|
+
// src/oidc/errors.ts
|
|
793
779
|
/**
|
|
794
780
|
* OIDC Discovery Error Mapping
|
|
795
781
|
*
|
|
@@ -869,8 +855,7 @@ function mapDiscoveryErrorToAPIError(error) {
|
|
|
869
855
|
});
|
|
870
856
|
}
|
|
871
857
|
}
|
|
872
|
-
|
|
873
|
-
//#region src/provider-reference.ts
|
|
858
|
+
// src/provider-reference.ts
|
|
874
859
|
const SSO_PROVIDER_STATE_KEY = "ssoProviderReference";
|
|
875
860
|
function serializeCanonical(value) {
|
|
876
861
|
if (value === null) return "null";
|
|
@@ -965,8 +950,7 @@ async function isCurrentSSOProviderReference(provider, reference) {
|
|
|
965
950
|
if (source.type === "persisted" && (reference.source.type !== "persisted" || source.recordId !== reference.source.recordId)) return false;
|
|
966
951
|
return reference.authenticationConfigurationFingerprint === await computeProviderAuthenticationFingerprint(provider);
|
|
967
952
|
}
|
|
968
|
-
|
|
969
|
-
//#region src/saml/parser.ts
|
|
953
|
+
// src/saml/parser.ts
|
|
970
954
|
const xmlParser = new XMLParser({
|
|
971
955
|
ignoreAttributes: false,
|
|
972
956
|
attributeNamePrefix: "@_",
|
|
@@ -999,8 +983,7 @@ function countAllNodes(obj, nodeName) {
|
|
|
999
983
|
else if (typeof value === "object" && value !== null) count += countAllNodes(value, nodeName);
|
|
1000
984
|
return count;
|
|
1001
985
|
}
|
|
1002
|
-
|
|
1003
|
-
//#region src/saml/algorithms.ts
|
|
986
|
+
// src/saml/algorithms.ts
|
|
1004
987
|
const SignatureAlgorithm = {
|
|
1005
988
|
RSA_SHA1: "http://www.w3.org/2000/09/xmldsig#rsa-sha1",
|
|
1006
989
|
RSA_SHA256: "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256",
|
|
@@ -1177,8 +1160,7 @@ function validateConfigAlgorithms(config, options = {}) {
|
|
|
1177
1160
|
}
|
|
1178
1161
|
}
|
|
1179
1162
|
const saml = typeof samlifyNamespace.SPMetadata === "function" && typeof samlifyNamespace.setSchemaValidator === "function" ? samlifyNamespace : samlifyDefault ?? samlifyNamespace;
|
|
1180
|
-
|
|
1181
|
-
//#region src/saml/assertions.ts
|
|
1163
|
+
// src/saml/assertions.ts
|
|
1182
1164
|
const SAML_ASSERTION_NAMESPACE = "urn:oasis:names:tc:SAML:2.0:assertion";
|
|
1183
1165
|
const SAML_PROTOCOL_NAMESPACE = "urn:oasis:names:tc:SAML:2.0:protocol";
|
|
1184
1166
|
const XML_SIGNATURE_NAMESPACE = "http://www.w3.org/2000/09/xmldsig#";
|
|
@@ -1254,8 +1236,7 @@ function verifySAMLAssertionSignature(samlContent, verificationOptions) {
|
|
|
1254
1236
|
throw assertionSignatureFailure();
|
|
1255
1237
|
}
|
|
1256
1238
|
}
|
|
1257
|
-
|
|
1258
|
-
//#region src/saml/error-codes.ts
|
|
1239
|
+
// src/saml/error-codes.ts
|
|
1259
1240
|
const SAML_ERROR_CODES = defineErrorCodes({
|
|
1260
1241
|
SINGLE_LOGOUT_NOT_ENABLED: "Single Logout is not enabled",
|
|
1261
1242
|
INVALID_LOGOUT_RESPONSE: "Invalid LogoutResponse",
|
|
@@ -1265,8 +1246,7 @@ const SAML_ERROR_CODES = defineErrorCodes({
|
|
|
1265
1246
|
SAML_PROVIDER_NOT_FOUND: "SAML provider not found",
|
|
1266
1247
|
CERT_SOURCE_MISSING: "samlConfig requires either a signing certificate (cert or idpMetadata.cert) or an idpMetadata.metadata XML document."
|
|
1267
1248
|
});
|
|
1268
|
-
|
|
1269
|
-
//#region src/saml/cert.ts
|
|
1249
|
+
// src/saml/cert.ts
|
|
1270
1250
|
/**
|
|
1271
1251
|
* IdP signing-certificate rules for SAML configs. Centralized so the runtime
|
|
1272
1252
|
* verification path (`createIdP`), the sanitizer (`getSSOProvider` and
|
|
@@ -1295,8 +1275,7 @@ function validateCertSources(config) {
|
|
|
1295
1275
|
const hasExplicitCert = config.idpMetadata?.cert !== void 0 || config.cert !== void 0;
|
|
1296
1276
|
if (!hasMetadataXml && !hasExplicitCert) throw APIError.from("BAD_REQUEST", SAML_ERROR_CODES.CERT_SOURCE_MISSING);
|
|
1297
1277
|
}
|
|
1298
|
-
|
|
1299
|
-
//#region src/saml/response-binding.ts
|
|
1278
|
+
// src/saml/response-binding.ts
|
|
1300
1279
|
const SAML_HTTP_POST_BINDING = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST";
|
|
1301
1280
|
const SAML_BEARER_CONFIRMATION_METHOD = "urn:oasis:names:tc:SAML:2.0:cm:bearer";
|
|
1302
1281
|
const SAML_METADATA_NAMESPACE = "urn:oasis:names:tc:SAML:2.0:metadata";
|
|
@@ -1473,8 +1452,7 @@ function validateSAMLResponseBinding(samlContent, options) {
|
|
|
1473
1452
|
validateBearerRecipient(assertion, expectedRecipients);
|
|
1474
1453
|
validateResponseDestination(response, expectedRecipients);
|
|
1475
1454
|
}
|
|
1476
|
-
|
|
1477
|
-
//#region src/saml/response-validation.ts
|
|
1455
|
+
// src/saml/response-validation.ts
|
|
1478
1456
|
function errorRedirectUrl(base, error, description) {
|
|
1479
1457
|
try {
|
|
1480
1458
|
const url = new URL(base);
|
|
@@ -1571,8 +1549,7 @@ function validateAudience(c, ctx) {
|
|
|
1571
1549
|
throw c.redirect(errorRedirectUrl(ctx.redirectUrl, "invalid_saml_response", "Audience mismatch"));
|
|
1572
1550
|
}
|
|
1573
1551
|
}
|
|
1574
|
-
|
|
1575
|
-
//#region src/user-resolution.ts
|
|
1552
|
+
// src/user-resolution.ts
|
|
1576
1553
|
const SSO_AUTHENTICATION_FAILURE = Symbol("SSO_AUTHENTICATION_FAILURE");
|
|
1577
1554
|
function isRecord$1(value) {
|
|
1578
1555
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -1658,8 +1635,7 @@ function getFailedSSOAuthenticationResult(error) {
|
|
|
1658
1635
|
if (!(error instanceof Error) || !(SSO_AUTHENTICATION_FAILURE in error) || error[SSO_AUTHENTICATION_FAILURE] !== true || !("result" in error)) return;
|
|
1659
1636
|
return error.result;
|
|
1660
1637
|
}
|
|
1661
|
-
|
|
1662
|
-
//#region src/routes/helpers.ts
|
|
1638
|
+
// src/routes/helpers.ts
|
|
1663
1639
|
/**
|
|
1664
1640
|
* Same as `normalizePem`, but applied across the resolved list of IdP signing
|
|
1665
1641
|
* certificates so multi-cert rotation configs survive the line-trim step.
|
|
@@ -1823,8 +1799,7 @@ function createSAMLPostForm(action, samlParam, samlValue, relayState) {
|
|
|
1823
1799
|
const html = `<!DOCTYPE html><html><body onload="document.forms[0].submit();"><form method="POST" action="${safeAction}"><input type="hidden" name="${safeSamlParam}" value="${safeSamlValue}" />${safeRelayState ? `<input type="hidden" name="RelayState" value="${safeRelayState}" />` : ""}<noscript><input type="submit" value="Continue" /></noscript></form></body></html>`;
|
|
1824
1800
|
return new Response(html, { headers: { "Content-Type": "text/html" } });
|
|
1825
1801
|
}
|
|
1826
|
-
|
|
1827
|
-
//#region src/routes/schemas.ts
|
|
1802
|
+
// src/routes/schemas.ts
|
|
1828
1803
|
const absoluteUrlSchema = z.url();
|
|
1829
1804
|
const samlRedirectUrlSchema = z.string().refine((url) => isSafeSAMLRedirectPath(url) || absoluteUrlSchema.safeParse(url).success, { message: "Expected an absolute URL or a relative path starting with /" });
|
|
1830
1805
|
function getSSOProviderAdditionalFields$1(options) {
|
|
@@ -1967,8 +1942,7 @@ function getUpdateSSOProviderBodySchema(options) {
|
|
|
1967
1942
|
...getSSOProviderAdditionalFieldsSchema(options).partial().shape
|
|
1968
1943
|
});
|
|
1969
1944
|
}
|
|
1970
|
-
|
|
1971
|
-
//#region src/routes/providers.ts
|
|
1945
|
+
// src/routes/providers.ts
|
|
1972
1946
|
const ADMIN_ROLES = ["owner", "admin"];
|
|
1973
1947
|
const OIDC_IDENTITY_BOUNDARY_FIELDS = [
|
|
1974
1948
|
"authorizationEndpoint",
|
|
@@ -2519,8 +2493,7 @@ const deleteSSOProvider = (options) => {
|
|
|
2519
2493
|
return ctx.json({ success: true });
|
|
2520
2494
|
});
|
|
2521
2495
|
};
|
|
2522
|
-
|
|
2523
|
-
//#region src/routes/domain-verification.ts
|
|
2496
|
+
// src/routes/domain-verification.ts
|
|
2524
2497
|
const DNS_LABEL_MAX_LENGTH = 63;
|
|
2525
2498
|
const DEFAULT_TOKEN_PREFIX = "better-auth-token";
|
|
2526
2499
|
const domainVerificationBodySchema = z.object({ providerId: z.string() });
|
|
@@ -2649,8 +2622,7 @@ const verifyDomain = (options) => {
|
|
|
2649
2622
|
ctx.setStatus(204);
|
|
2650
2623
|
});
|
|
2651
2624
|
};
|
|
2652
|
-
|
|
2653
|
-
//#region src/saml-state.ts
|
|
2625
|
+
// src/saml-state.ts
|
|
2654
2626
|
async function generateRelayState(c, link, providerReference) {
|
|
2655
2627
|
const callbackURL = c.body.callbackURL;
|
|
2656
2628
|
if (!callbackURL) throw new APIError("BAD_REQUEST", { message: "callbackURL is required" });
|
|
@@ -2700,8 +2672,7 @@ async function parseRelayState(c) {
|
|
|
2700
2672
|
if (!parsedData.errorURL) parsedData.errorURL = errorURL;
|
|
2701
2673
|
return parsedData;
|
|
2702
2674
|
}
|
|
2703
|
-
|
|
2704
|
-
//#region src/saml/timestamp.ts
|
|
2675
|
+
// src/saml/timestamp.ts
|
|
2705
2676
|
/**
|
|
2706
2677
|
* Validates SAML assertion timestamp conditions (NotBefore/NotOnOrAfter).
|
|
2707
2678
|
* Prevents acceptance of expired or future-dated assertions.
|
|
@@ -2741,8 +2712,7 @@ function validateSAMLTimestamp(conditions, options = {}) {
|
|
|
2741
2712
|
});
|
|
2742
2713
|
}
|
|
2743
2714
|
}
|
|
2744
|
-
|
|
2745
|
-
//#region src/routes/saml-pipeline.ts
|
|
2715
|
+
// src/routes/saml-pipeline.ts
|
|
2746
2716
|
function isSameSSOProviderReference(left, right) {
|
|
2747
2717
|
if (left.providerId !== right.providerId || left.authenticationConfigurationFingerprint !== right.authenticationConfigurationFingerprint || left.source.type !== right.source.type) return false;
|
|
2748
2718
|
return left.source.type === "configured" ? true : right.source.type === "persisted" && left.source.recordId === right.source.recordId;
|
|
@@ -2823,20 +2793,16 @@ async function getSAMLResponseBindingContent(sp, samlContent) {
|
|
|
2823
2793
|
/**
|
|
2824
2794
|
* Extracts the Assertion ID from a SAML response XML.
|
|
2825
2795
|
* Used for replay protection per SAML 2.0 Core section 2.3.3.
|
|
2796
|
+
*
|
|
2797
|
+
* Reads the ID through the DOM so character references are decoded the same
|
|
2798
|
+
* way the signature check decodes them: re-spelling the ID keeps the
|
|
2799
|
+
* signature valid, so it must not change the replay key.
|
|
2826
2800
|
*/
|
|
2827
2801
|
function extractAssertionId(samlContent) {
|
|
2828
2802
|
try {
|
|
2829
|
-
const
|
|
2830
|
-
|
|
2831
|
-
|
|
2832
|
-
removeNSPrefix: true
|
|
2833
|
-
}).parse(samlContent);
|
|
2834
|
-
const response = parsed.Response || parsed["samlp:Response"];
|
|
2835
|
-
if (!response) return null;
|
|
2836
|
-
const rawAssertion = response.Assertion || response["saml:Assertion"];
|
|
2837
|
-
const assertion = Array.isArray(rawAssertion) ? rawAssertion[0] : rawAssertion;
|
|
2838
|
-
if (!assertion) return null;
|
|
2839
|
-
return assertion["@_ID"] || null;
|
|
2803
|
+
const response = new DOMParser().parseFromString(samlContent, "text/xml").documentElement;
|
|
2804
|
+
if (response?.localName !== "Response") return null;
|
|
2805
|
+
return Array.from(response.childNodes).find((node) => node.nodeType === 1 && node.localName === "Assertion")?.getAttribute("ID") || null;
|
|
2840
2806
|
} catch {
|
|
2841
2807
|
return null;
|
|
2842
2808
|
}
|
|
@@ -2999,7 +2965,7 @@ async function processSAMLResponse(ctx, params, options) {
|
|
|
2999
2965
|
id: extract.nameID,
|
|
3000
2966
|
email: (attr(mapping.email || "email") || extract.nameID || "").toLowerCase(),
|
|
3001
2967
|
name: [attr(mapping.firstName || "givenName"), attr(mapping.lastName || "surname")].filter(Boolean).join(" ") || attr(mapping.name || "displayName") || extract.nameID,
|
|
3002
|
-
emailVerified: options?.trustEmailVerified && mapping.emailVerified ?
|
|
2968
|
+
emailVerified: options?.trustEmailVerified && mapping.emailVerified ? parseStringBoolean(attr(mapping.emailVerified)) ?? false : false
|
|
3003
2969
|
};
|
|
3004
2970
|
if (!userInfo.id || !userInfo.email) {
|
|
3005
2971
|
ctx.context.logger.error("Missing essential user info from SAML response", {
|
|
@@ -3140,8 +3106,7 @@ async function processSAMLResponse(ctx, params, options) {
|
|
|
3140
3106
|
}
|
|
3141
3107
|
return samlRedirectUrl;
|
|
3142
3108
|
}
|
|
3143
|
-
|
|
3144
|
-
//#region src/routes/sso.ts
|
|
3109
|
+
// src/routes/sso.ts
|
|
3145
3110
|
const BUILT_IN_ACCOUNT_PROVIDER_IDS = [
|
|
3146
3111
|
"credential",
|
|
3147
3112
|
"email-otp",
|
|
@@ -3939,7 +3904,7 @@ async function handleOIDCCallback(ctx, options, providerId, stateData, parsedPro
|
|
|
3939
3904
|
...Object.fromEntries(Object.entries(mapping.extraFields || {}).map(([key, value]) => [key, rawUserInfo[value]])),
|
|
3940
3905
|
id: readStringClaim(rawUserInfo, "sub"),
|
|
3941
3906
|
email: readEmailClaim(rawUserInfo),
|
|
3942
|
-
emailVerified: options?.trustEmailVerified ?
|
|
3907
|
+
emailVerified: options?.trustEmailVerified ? parseStringBoolean(rawUserInfo[mapping.emailVerified || "email_verified"]) ?? false : false,
|
|
3943
3908
|
name: readStringClaim(rawUserInfo, mapping.name || "name"),
|
|
3944
3909
|
image: readStringClaim(rawUserInfo, mapping.image || "picture")
|
|
3945
3910
|
};
|
|
@@ -3950,7 +3915,7 @@ async function handleOIDCCallback(ctx, options, providerId, stateData, parsedPro
|
|
|
3950
3915
|
...Object.fromEntries(Object.entries(mapping.extraFields || {}).map(([key, value]) => [key, idToken[value]])),
|
|
3951
3916
|
id: idToken.sub,
|
|
3952
3917
|
email: readEmailClaim(idToken),
|
|
3953
|
-
emailVerified: options?.trustEmailVerified ?
|
|
3918
|
+
emailVerified: options?.trustEmailVerified ? parseStringBoolean(idToken[mapping.emailVerified || "email_verified"]) ?? false : false,
|
|
3954
3919
|
name: readStringClaim(idToken, mapping.name || "name"),
|
|
3955
3920
|
image: readStringClaim(idToken, mapping.image || "picture")
|
|
3956
3921
|
};
|
|
@@ -4423,7 +4388,7 @@ const initiateSLO = (options) => {
|
|
|
4423
4388
|
const session = ctx.context.session;
|
|
4424
4389
|
const sessionLookupKey = `${SAML_SESSION_BY_ID_PREFIX}${session.session.id}`;
|
|
4425
4390
|
const sessionLookup = await ctx.context.internalAdapter.findVerificationValue(sessionLookupKey);
|
|
4426
|
-
let nameID
|
|
4391
|
+
let nameID;
|
|
4427
4392
|
let sessionIndex;
|
|
4428
4393
|
let samlSessionKey;
|
|
4429
4394
|
if (sessionLookup) {
|
|
@@ -4432,11 +4397,15 @@ const initiateSLO = (options) => {
|
|
|
4432
4397
|
if (stored) {
|
|
4433
4398
|
const data = safeJsonParse(stored.value);
|
|
4434
4399
|
if (data) {
|
|
4435
|
-
nameID = data.nameID
|
|
4400
|
+
nameID = data.nameID;
|
|
4436
4401
|
sessionIndex = data.sessionIndex;
|
|
4437
4402
|
}
|
|
4438
4403
|
}
|
|
4439
4404
|
}
|
|
4405
|
+
if (!nameID) {
|
|
4406
|
+
const [account] = (await ctx.context.internalAdapter.findAccounts(session.user.id)).filter((account) => account.providerId === providerId).sort((a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime());
|
|
4407
|
+
nameID = account?.accountId ?? session.user.email;
|
|
4408
|
+
}
|
|
4440
4409
|
const logoutRequest = sp.createLogoutRequest(idp, "redirect", {
|
|
4441
4410
|
logoutNameID: nameID,
|
|
4442
4411
|
sessionIndex,
|
|
@@ -4455,8 +4424,7 @@ const initiateSLO = (options) => {
|
|
|
4455
4424
|
throw ctx.redirect(logoutRequest.context);
|
|
4456
4425
|
});
|
|
4457
4426
|
};
|
|
4458
|
-
|
|
4459
|
-
//#region src/index.ts
|
|
4427
|
+
// src/index.ts
|
|
4460
4428
|
saml.setSchemaValidator({ async validate(xml) {
|
|
4461
4429
|
if (XMLValidator.validate(xml, { allowBooleanAttributes: true }) === true) return "SUCCESS_VALIDATE_XML";
|
|
4462
4430
|
throw "ERR_INVALID_XML";
|
|
@@ -4501,6 +4469,53 @@ function assertNoAdditionalFieldCollisions(options) {
|
|
|
4501
4469
|
if (builtInFieldNames.has(fieldName)) throw new Error(`ssoProvider additional field "${key}" maps to built-in field "${fieldName}"`);
|
|
4502
4470
|
}
|
|
4503
4471
|
}
|
|
4472
|
+
const SAML_SESSION_RECORD_PAGE_SIZE = 100;
|
|
4473
|
+
async function findSAMLSessionRecord(ctx, identifier, isOwnRecord) {
|
|
4474
|
+
for (let offset = 0;; offset += SAML_SESSION_RECORD_PAGE_SIZE) {
|
|
4475
|
+
const page = await ctx.adapter.findMany({
|
|
4476
|
+
model: "verification",
|
|
4477
|
+
where: [{
|
|
4478
|
+
field: "identifier",
|
|
4479
|
+
value: identifier
|
|
4480
|
+
}],
|
|
4481
|
+
sortBy: {
|
|
4482
|
+
field: "createdAt",
|
|
4483
|
+
direction: "desc"
|
|
4484
|
+
},
|
|
4485
|
+
limit: SAML_SESSION_RECORD_PAGE_SIZE,
|
|
4486
|
+
offset
|
|
4487
|
+
});
|
|
4488
|
+
const record = page.find(isOwnRecord);
|
|
4489
|
+
if (record || page.length < SAML_SESSION_RECORD_PAGE_SIZE) return record;
|
|
4490
|
+
}
|
|
4491
|
+
}
|
|
4492
|
+
/**
|
|
4493
|
+
* SLO records are written with the session's expiry at sign-in. Move it when a
|
|
4494
|
+
* refresh extends the session, so expired-row cleanup doesn't drop them early.
|
|
4495
|
+
*/
|
|
4496
|
+
async function extendSAMLSessionRecords(ctx, session) {
|
|
4497
|
+
const lookupKey = `${SAML_SESSION_BY_ID_PREFIX}${session.id}`;
|
|
4498
|
+
const lookup = await ctx.internalAdapter.findVerificationValue(lookupKey);
|
|
4499
|
+
const expiresAt = new Date(session.expiresAt);
|
|
4500
|
+
if (!lookup || new Date(lookup.expiresAt) >= expiresAt) return;
|
|
4501
|
+
const isOwnRecord = (record) => safeJsonParse(record.value)?.sessionId === session.id;
|
|
4502
|
+
const latest = await ctx.internalAdapter.findVerificationValue(lookup.value);
|
|
4503
|
+
const secondaryStorageOnly = ctx.options.secondaryStorage && !ctx.options.verification?.storeInDatabase;
|
|
4504
|
+
if (latest && secondaryStorageOnly) {
|
|
4505
|
+
if (isOwnRecord(latest)) await ctx.internalAdapter.updateVerificationByIdentifier(lookup.value, { expiresAt });
|
|
4506
|
+
} else if (latest) {
|
|
4507
|
+
const record = await findSAMLSessionRecord(ctx, latest.identifier, isOwnRecord);
|
|
4508
|
+
if (record) await ctx.adapter.update({
|
|
4509
|
+
model: "verification",
|
|
4510
|
+
where: [{
|
|
4511
|
+
field: "id",
|
|
4512
|
+
value: record.id
|
|
4513
|
+
}],
|
|
4514
|
+
update: { expiresAt }
|
|
4515
|
+
});
|
|
4516
|
+
}
|
|
4517
|
+
await ctx.internalAdapter.updateVerificationByIdentifier(lookupKey, { expiresAt });
|
|
4518
|
+
}
|
|
4504
4519
|
function sso(options) {
|
|
4505
4520
|
assertNoAdditionalFieldCollisions(options);
|
|
4506
4521
|
const optionsWithStore = options;
|
|
@@ -4533,8 +4548,13 @@ function sso(options) {
|
|
|
4533
4548
|
version: PACKAGE_VERSION,
|
|
4534
4549
|
init(ctx) {
|
|
4535
4550
|
const existing = ctx.skipOriginCheck;
|
|
4536
|
-
|
|
4537
|
-
|
|
4551
|
+
return {
|
|
4552
|
+
...existing !== true && { context: { skipOriginCheck: [...Array.isArray(existing) ? existing : [], ...SAML_SKIP_ORIGIN_CHECK_PATHS] } },
|
|
4553
|
+
options: { databaseHooks: { session: { update: { async after(session) {
|
|
4554
|
+
if (!options?.saml?.enableSingleLogout) return;
|
|
4555
|
+
await extendSAMLSessionRecords(ctx, session).catch((error) => ctx.logger.warn("Failed to extend SAML session records", { error }));
|
|
4556
|
+
} } } } }
|
|
4557
|
+
};
|
|
4538
4558
|
},
|
|
4539
4559
|
endpoints,
|
|
4540
4560
|
hooks: {
|
|
@@ -4624,5 +4644,4 @@ function sso(options) {
|
|
|
4624
4644
|
options
|
|
4625
4645
|
};
|
|
4626
4646
|
}
|
|
4627
|
-
//#endregion
|
|
4628
4647
|
export { DEFAULT_CLOCK_SKEW_MS, DEFAULT_MAX_SAML_METADATA_SIZE, DEFAULT_MAX_SAML_RESPONSE_SIZE, DataEncryptionAlgorithm, DigestAlgorithm, DiscoveryError, KeyEncryptionAlgorithm, REQUIRED_DISCOVERY_FIELDS, SignatureAlgorithm, computeDiscoveryUrl, deriveSAMLIdentityProviderEntityID, deriveSAMLServiceProviderPolicy, discoverOIDCConfig, fetchDiscoveryDocument, needsRuntimeDiscovery, normalizeDiscoveryUrls, normalizeUrl, selectTokenEndpointAuthMethod, sso, validateDiscoveryDocument, validateDiscoveryUrl, validateSAMLTimestamp };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@better-auth/sso",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.22",
|
|
4
4
|
"description": "SSO plugin for Better Auth",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -64,24 +64,24 @@
|
|
|
64
64
|
"zod": "^4.5.4"
|
|
65
65
|
},
|
|
66
66
|
"devDependencies": {
|
|
67
|
+
"@better-auth/core": "1.7.22",
|
|
68
|
+
"@better-auth/kysely-adapter": "1.7.22",
|
|
67
69
|
"@types/body-parser": "^1.19.6",
|
|
68
70
|
"@types/express": "^5.0.6",
|
|
71
|
+
"better-auth": "1.7.22",
|
|
69
72
|
"better-call": "1.4.5",
|
|
70
73
|
"body-parser": "^2.3.0",
|
|
71
74
|
"express": "^5.2.1",
|
|
72
75
|
"kysely": "^0.28.17 || ^0.29.0",
|
|
73
76
|
"oauth2-mock-server": "^9.0.0",
|
|
74
|
-
"tsdown": "0.23.1"
|
|
75
|
-
"@better-auth/core": "1.7.20",
|
|
76
|
-
"@better-auth/kysely-adapter": "1.7.20",
|
|
77
|
-
"better-auth": "1.7.20"
|
|
77
|
+
"tsdown": "0.23.1"
|
|
78
78
|
},
|
|
79
79
|
"peerDependencies": {
|
|
80
|
+
"@better-auth/core": "^1.7.22",
|
|
80
81
|
"@better-auth/utils": "^0.4.2 || ^0.5.0",
|
|
81
82
|
"@better-fetch/fetch": "1.3.3",
|
|
82
|
-
"better-
|
|
83
|
-
"
|
|
84
|
-
"better-auth": "^1.7.20"
|
|
83
|
+
"better-auth": "^1.7.22",
|
|
84
|
+
"better-call": "1.4.5"
|
|
85
85
|
},
|
|
86
86
|
"scripts": {
|
|
87
87
|
"build": "tsdown",
|