@better-auth/sso 1.4.0-beta.2 → 1.4.0-beta.4

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,17 +1,17 @@
1
1
 
2
- > @better-auth/sso@1.4.0-beta.2 build /home/runner/work/better-auth/better-auth/packages/sso
2
+ > @better-auth/sso@1.4.0-beta.4 build /home/runner/work/better-auth/better-auth/packages/sso
3
3
  > unbuild
4
4
 
5
5
  [info] Automatically detected entries: src/index, src/client [esm] [cjs] [dts]
6
6
  [info] Building sso
7
7
  [success] Build succeeded for sso
8
- [log] dist/index.cjs (total size: 66.4 kB, chunk size: 66.4 kB, exports: sso)
8
+ [log] dist/index.cjs (total size: 67.2 kB, chunk size: 67.2 kB, exports: sso)
9
9
 
10
10
  [log] dist/client.cjs (total size: 141 B, chunk size: 141 B, exports: ssoClient)
11
11
 
12
- [log] dist/index.mjs (total size: 64.7 kB, chunk size: 64.7 kB, exports: sso)
12
+ [log] dist/index.mjs (total size: 65.5 kB, chunk size: 65.5 kB, exports: sso)
13
13
 
14
14
  [log] dist/client.mjs (total size: 117 B, chunk size: 117 B, exports: ssoClient)
15
15
 
16
- Σ Total dist size (byte size): 258 kB
16
+ Σ Total dist size (byte size): 260 kB
17
17
  [log]
package/dist/index.cjs CHANGED
@@ -76,8 +76,18 @@ const sso = (options) => {
76
76
  });
77
77
  }
78
78
  const parsedSamlConfig = JSON.parse(provider.samlConfig);
79
- const sp = saml__namespace.ServiceProvider({
79
+ const sp = parsedSamlConfig.spMetadata.metadata ? saml__namespace.ServiceProvider({
80
80
  metadata: parsedSamlConfig.spMetadata.metadata
81
+ }) : saml__namespace.SPMetadata({
82
+ entityID: parsedSamlConfig.spMetadata?.entityID || parsedSamlConfig.issuer,
83
+ assertionConsumerService: [
84
+ {
85
+ Binding: "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST",
86
+ Location: parsedSamlConfig.callbackUrl || `${ctx.context.baseURL}/sso/saml2/sp/acs/${provider.id}`
87
+ }
88
+ ],
89
+ wantMessageSigned: parsedSamlConfig.wantAssertionsSigned || false,
90
+ nameIDFormat: parsedSamlConfig.identifierFormat ? [parsedSamlConfig.identifierFormat] : void 0
81
91
  });
82
92
  return new Response(sp.getMetadata(), {
83
93
  headers: {
@@ -711,10 +721,10 @@ const sso = (options) => {
711
721
  allowCreate: true
712
722
  });
713
723
  const idp = saml__namespace.IdentityProvider({
714
- metadata: parsedSamlConfig.idpMetadata.metadata,
715
- entityID: parsedSamlConfig.idpMetadata.entityID,
716
- encryptCert: parsedSamlConfig.idpMetadata.cert,
717
- singleSignOnService: parsedSamlConfig.idpMetadata.singleSignOnService
724
+ metadata: parsedSamlConfig.idpMetadata?.metadata,
725
+ entityID: parsedSamlConfig.idpMetadata?.entityID,
726
+ encryptCert: parsedSamlConfig.idpMetadata?.cert,
727
+ singleSignOnService: parsedSamlConfig.idpMetadata?.singleSignOnService
718
728
  });
719
729
  const loginRequest = sp.createLoginRequest(
720
730
  idp,
@@ -1103,7 +1113,8 @@ const sso = (options) => {
1103
1113
  isAssertionEncrypted: spData?.isAssertionEncrypted || false,
1104
1114
  encPrivateKey: spData?.encPrivateKey,
1105
1115
  encPrivateKeyPass: spData?.encPrivateKeyPass,
1106
- wantMessageSigned: parsedSamlConfig.wantAssertionsSigned || false
1116
+ wantMessageSigned: parsedSamlConfig.wantAssertionsSigned || false,
1117
+ nameIDFormat: parsedSamlConfig.identifierFormat ? [parsedSamlConfig.identifierFormat] : void 0
1107
1118
  });
1108
1119
  let parsedResponse;
1109
1120
  try {
@@ -1337,13 +1348,14 @@ const sso = (options) => {
1337
1348
  assertionConsumerService: [
1338
1349
  {
1339
1350
  Binding: "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST",
1340
- Location: parsedSamlConfig.callbackUrl || `${ctx.context.baseURL}/sso/saml2/sp/acs`
1351
+ Location: parsedSamlConfig.callbackUrl || `${ctx.context.baseURL}/sso/saml2/sp/acs/${providerId}`
1341
1352
  }
1342
1353
  ],
1343
1354
  wantMessageSigned: parsedSamlConfig.wantAssertionsSigned || false,
1344
1355
  metadata: parsedSamlConfig.spMetadata?.metadata,
1345
1356
  privateKey: parsedSamlConfig.spMetadata?.privateKey || parsedSamlConfig.privateKey,
1346
- privateKeyPass: parsedSamlConfig.spMetadata?.privateKeyPass
1357
+ privateKeyPass: parsedSamlConfig.spMetadata?.privateKeyPass,
1358
+ nameIDFormat: parsedSamlConfig.identifierFormat ? [parsedSamlConfig.identifierFormat] : void 0
1347
1359
  });
1348
1360
  const idpData = parsedSamlConfig.idpMetadata;
1349
1361
  const idp = !idpData?.metadata ? saml__namespace.IdentityProvider({
package/dist/index.mjs CHANGED
@@ -59,8 +59,18 @@ const sso = (options) => {
59
59
  });
60
60
  }
61
61
  const parsedSamlConfig = JSON.parse(provider.samlConfig);
62
- const sp = saml.ServiceProvider({
62
+ const sp = parsedSamlConfig.spMetadata.metadata ? saml.ServiceProvider({
63
63
  metadata: parsedSamlConfig.spMetadata.metadata
64
+ }) : saml.SPMetadata({
65
+ entityID: parsedSamlConfig.spMetadata?.entityID || parsedSamlConfig.issuer,
66
+ assertionConsumerService: [
67
+ {
68
+ Binding: "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST",
69
+ Location: parsedSamlConfig.callbackUrl || `${ctx.context.baseURL}/sso/saml2/sp/acs/${provider.id}`
70
+ }
71
+ ],
72
+ wantMessageSigned: parsedSamlConfig.wantAssertionsSigned || false,
73
+ nameIDFormat: parsedSamlConfig.identifierFormat ? [parsedSamlConfig.identifierFormat] : void 0
64
74
  });
65
75
  return new Response(sp.getMetadata(), {
66
76
  headers: {
@@ -694,10 +704,10 @@ const sso = (options) => {
694
704
  allowCreate: true
695
705
  });
696
706
  const idp = saml.IdentityProvider({
697
- metadata: parsedSamlConfig.idpMetadata.metadata,
698
- entityID: parsedSamlConfig.idpMetadata.entityID,
699
- encryptCert: parsedSamlConfig.idpMetadata.cert,
700
- singleSignOnService: parsedSamlConfig.idpMetadata.singleSignOnService
707
+ metadata: parsedSamlConfig.idpMetadata?.metadata,
708
+ entityID: parsedSamlConfig.idpMetadata?.entityID,
709
+ encryptCert: parsedSamlConfig.idpMetadata?.cert,
710
+ singleSignOnService: parsedSamlConfig.idpMetadata?.singleSignOnService
701
711
  });
702
712
  const loginRequest = sp.createLoginRequest(
703
713
  idp,
@@ -1086,7 +1096,8 @@ const sso = (options) => {
1086
1096
  isAssertionEncrypted: spData?.isAssertionEncrypted || false,
1087
1097
  encPrivateKey: spData?.encPrivateKey,
1088
1098
  encPrivateKeyPass: spData?.encPrivateKeyPass,
1089
- wantMessageSigned: parsedSamlConfig.wantAssertionsSigned || false
1099
+ wantMessageSigned: parsedSamlConfig.wantAssertionsSigned || false,
1100
+ nameIDFormat: parsedSamlConfig.identifierFormat ? [parsedSamlConfig.identifierFormat] : void 0
1090
1101
  });
1091
1102
  let parsedResponse;
1092
1103
  try {
@@ -1320,13 +1331,14 @@ const sso = (options) => {
1320
1331
  assertionConsumerService: [
1321
1332
  {
1322
1333
  Binding: "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST",
1323
- Location: parsedSamlConfig.callbackUrl || `${ctx.context.baseURL}/sso/saml2/sp/acs`
1334
+ Location: parsedSamlConfig.callbackUrl || `${ctx.context.baseURL}/sso/saml2/sp/acs/${providerId}`
1324
1335
  }
1325
1336
  ],
1326
1337
  wantMessageSigned: parsedSamlConfig.wantAssertionsSigned || false,
1327
1338
  metadata: parsedSamlConfig.spMetadata?.metadata,
1328
1339
  privateKey: parsedSamlConfig.spMetadata?.privateKey || parsedSamlConfig.privateKey,
1329
- privateKeyPass: parsedSamlConfig.spMetadata?.privateKeyPass
1340
+ privateKeyPass: parsedSamlConfig.spMetadata?.privateKeyPass,
1341
+ nameIDFormat: parsedSamlConfig.identifierFormat ? [parsedSamlConfig.identifierFormat] : void 0
1330
1342
  });
1331
1343
  const idpData = parsedSamlConfig.idpMetadata;
1332
1344
  const idp = !idpData?.metadata ? saml.IdentityProvider({
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.2",
4
+ "version": "1.4.0-beta.4",
5
5
  "main": "dist/index.cjs",
6
6
  "license": "MIT",
7
7
  "keywords": [
@@ -58,15 +58,15 @@
58
58
  "body-parser": "^2.2.0",
59
59
  "express": "^5.1.0",
60
60
  "unbuild": "3.6.1",
61
- "better-auth": "^1.4.0-beta.2"
61
+ "better-auth": "^1.4.0-beta.4"
62
62
  },
63
63
  "peerDependencies": {
64
- "better-auth": "1.4.0-beta.2"
64
+ "better-auth": "1.4.0-beta.4"
65
65
  },
66
66
  "scripts": {
67
67
  "test": "vitest",
68
68
  "build": "unbuild",
69
- "typecheck": "tsc --noEmit",
70
- "dev": "unbuild --watch"
69
+ "dev": "unbuild --watch",
70
+ "typecheck": "tsc --project tsconfig.json"
71
71
  }
72
72
  }
package/src/index.ts CHANGED
@@ -252,6 +252,7 @@ export const sso = (options?: SSOOptions) => {
252
252
  },
253
253
  async (ctx) => {
254
254
  const provider = await ctx.context.adapter.findOne<{
255
+ id: string;
255
256
  samlConfig: string;
256
257
  }>({
257
258
  model: "ssoProvider",
@@ -268,10 +269,29 @@ export const sso = (options?: SSOOptions) => {
268
269
  });
269
270
  }
270
271
 
271
- const parsedSamlConfig = JSON.parse(provider.samlConfig);
272
- const sp = saml.ServiceProvider({
273
- metadata: parsedSamlConfig.spMetadata.metadata,
274
- });
272
+ const parsedSamlConfig: SAMLConfig = JSON.parse(provider.samlConfig);
273
+ const sp = parsedSamlConfig.spMetadata.metadata
274
+ ? saml.ServiceProvider({
275
+ metadata: parsedSamlConfig.spMetadata.metadata,
276
+ })
277
+ : saml.SPMetadata({
278
+ entityID:
279
+ parsedSamlConfig.spMetadata?.entityID ||
280
+ parsedSamlConfig.issuer,
281
+ assertionConsumerService: [
282
+ {
283
+ Binding: "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST",
284
+ Location:
285
+ parsedSamlConfig.callbackUrl ||
286
+ `${ctx.context.baseURL}/sso/saml2/sp/acs/${provider.id}`,
287
+ },
288
+ ],
289
+ wantMessageSigned:
290
+ parsedSamlConfig.wantAssertionsSigned || false,
291
+ nameIDFormat: parsedSamlConfig.identifierFormat
292
+ ? [parsedSamlConfig.identifierFormat]
293
+ : undefined,
294
+ });
275
295
  return new Response(sp.getMetadata(), {
276
296
  headers: {
277
297
  "Content-Type": "application/xml",
@@ -1074,7 +1094,7 @@ export const sso = (options?: SSOOptions) => {
1074
1094
  });
1075
1095
  }
1076
1096
  if (provider.samlConfig) {
1077
- const parsedSamlConfig =
1097
+ const parsedSamlConfig: SAMLConfig =
1078
1098
  typeof provider.samlConfig === "object"
1079
1099
  ? provider.samlConfig
1080
1100
  : JSON.parse(provider.samlConfig as unknown as string);
@@ -1084,11 +1104,11 @@ export const sso = (options?: SSOOptions) => {
1084
1104
  });
1085
1105
 
1086
1106
  const idp = saml.IdentityProvider({
1087
- metadata: parsedSamlConfig.idpMetadata.metadata,
1088
- entityID: parsedSamlConfig.idpMetadata.entityID,
1089
- encryptCert: parsedSamlConfig.idpMetadata.cert,
1107
+ metadata: parsedSamlConfig.idpMetadata?.metadata,
1108
+ entityID: parsedSamlConfig.idpMetadata?.entityID,
1109
+ encryptCert: parsedSamlConfig.idpMetadata?.cert,
1090
1110
  singleSignOnService:
1091
- parsedSamlConfig.idpMetadata.singleSignOnService,
1111
+ parsedSamlConfig.idpMetadata?.singleSignOnService,
1092
1112
  });
1093
1113
  const loginRequest = sp.createLoginRequest(
1094
1114
  idp,
@@ -1577,6 +1597,9 @@ export const sso = (options?: SSOOptions) => {
1577
1597
  encPrivateKey: spData?.encPrivateKey,
1578
1598
  encPrivateKeyPass: spData?.encPrivateKeyPass,
1579
1599
  wantMessageSigned: parsedSamlConfig.wantAssertionsSigned || false,
1600
+ nameIDFormat: parsedSamlConfig.identifierFormat
1601
+ ? [parsedSamlConfig.identifierFormat]
1602
+ : undefined,
1580
1603
  });
1581
1604
 
1582
1605
  let parsedResponse: FlowResult;
@@ -1864,7 +1887,7 @@ export const sso = (options?: SSOOptions) => {
1864
1887
  Binding: "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST",
1865
1888
  Location:
1866
1889
  parsedSamlConfig.callbackUrl ||
1867
- `${ctx.context.baseURL}/sso/saml2/sp/acs`,
1890
+ `${ctx.context.baseURL}/sso/saml2/sp/acs/${providerId}`,
1868
1891
  },
1869
1892
  ],
1870
1893
  wantMessageSigned: parsedSamlConfig.wantAssertionsSigned || false,
@@ -1873,6 +1896,9 @@ export const sso = (options?: SSOOptions) => {
1873
1896
  parsedSamlConfig.spMetadata?.privateKey ||
1874
1897
  parsedSamlConfig.privateKey,
1875
1898
  privateKeyPass: parsedSamlConfig.spMetadata?.privateKeyPass,
1899
+ nameIDFormat: parsedSamlConfig.identifierFormat
1900
+ ? [parsedSamlConfig.identifierFormat]
1901
+ : undefined,
1876
1902
  });
1877
1903
 
1878
1904
  // Update where we construct the IdP
package/src/saml.test.ts CHANGED
@@ -242,7 +242,7 @@ const certificate = `
242
242
  yyoWAJDUHiAmvFA=
243
243
  -----END CERTIFICATE-----
244
244
  `;
245
- const idpEncyptionKey = `
245
+ const idpEncryptionKey = `
246
246
  -----BEGIN RSA PRIVATE KEY-----
247
247
  Proc-Type: 4,ENCRYPTED
248
248
  DEK-Info: DES-EDE3-CBC,860FDB9F3BE14699
@@ -274,7 +274,7 @@ const idpEncyptionKey = `
274
274
  ISbutnQPUN5fsaIsgKDIV3T7n6519t6brobcW5bdigmf5ebFeZJ16/lYy6V77UM5
275
275
  -----END RSA PRIVATE KEY-----
276
276
  `;
277
- const spEncyptionKey = `
277
+ const spEncryptionKey = `
278
278
  -----BEGIN RSA PRIVATE KEY-----
279
279
  Proc-Type: 4,ENCRYPTED
280
280
  DEK-Info: DES-EDE3-CBC,860FDB9F3BE14699
@@ -698,7 +698,7 @@ describe("SAML SSO", async () => {
698
698
  privateKey: idpPrivateKey,
699
699
  privateKeyPass: "q9ALNhGT5EhfcRmp8Pg7e9zTQeP2x1bW",
700
700
  isAssertionEncrypted: true,
701
- encPrivateKey: idpEncyptionKey,
701
+ encPrivateKey: idpEncryptionKey,
702
702
  encPrivateKeyPass: "g7hGcRmp8PxT5QeP2q9Ehf1bWe9zTALN",
703
703
  },
704
704
  spMetadata: {
@@ -707,7 +707,7 @@ describe("SAML SSO", async () => {
707
707
  privateKey: spPrivateKey,
708
708
  privateKeyPass: "VHOSp5RUiBcrsjrcAuXFwU1NKCkGA8px",
709
709
  isAssertionEncrypted: true,
710
- encPrivateKey: spEncyptionKey,
710
+ encPrivateKey: spEncryptionKey,
711
711
  encPrivateKeyPass: "BXFNKpxrsjrCkGA8cAu5wUVHOSpci1RU",
712
712
  },
713
713
  identifierFormat:
@@ -754,7 +754,7 @@ describe("SAML SSO", async () => {
754
754
  privateKey: idpPrivateKey,
755
755
  privateKeyPass: "q9ALNhGT5EhfcRmp8Pg7e9zTQeP2x1bW",
756
756
  isAssertionEncrypted: true,
757
- encPrivateKey: idpEncyptionKey,
757
+ encPrivateKey: idpEncryptionKey,
758
758
  encPrivateKeyPass: "g7hGcRmp8PxT5QeP2q9Ehf1bWe9zTALN",
759
759
  },
760
760
  spMetadata: {
@@ -763,7 +763,7 @@ describe("SAML SSO", async () => {
763
763
  privateKey: spPrivateKey,
764
764
  privateKeyPass: "VHOSp5RUiBcrsjrcAuXFwU1NKCkGA8px",
765
765
  isAssertionEncrypted: true,
766
- encPrivateKey: spEncyptionKey,
766
+ encPrivateKey: spEncryptionKey,
767
767
  encPrivateKeyPass: "BXFNKpxrsjrCkGA8cAu5wUVHOSpci1RU",
768
768
  },
769
769
  identifierFormat:
@@ -782,6 +782,69 @@ describe("SAML SSO", async () => {
782
782
  expect(spMetadataRes.status).toBe(200);
783
783
  expect(spMetadataResResValue).toBe(spMetadata);
784
784
  });
785
+ it("Should fetch sp metadata", async () => {
786
+ const headers = await getAuthHeaders();
787
+ await authClient.signIn.email(testUser, {
788
+ throw: true,
789
+ onSuccess: setCookieToHeader(headers),
790
+ });
791
+ const issuer = "http://localhost:8081";
792
+ const provider = await auth.api.registerSSOProvider({
793
+ body: {
794
+ providerId: "saml-provider-1",
795
+ issuer: issuer,
796
+ domain: issuer,
797
+ samlConfig: {
798
+ entryPoint: mockIdP.metadataUrl,
799
+ cert: certificate,
800
+ callbackUrl: `${issuer}/api/sso/saml2/sp/acs`,
801
+ wantAssertionsSigned: false,
802
+ signatureAlgorithm: "sha256",
803
+ digestAlgorithm: "sha256",
804
+ idpMetadata: {
805
+ metadata: idpMetadata,
806
+ privateKey: idpPrivateKey,
807
+ privateKeyPass: "q9ALNhGT5EhfcRmp8Pg7e9zTQeP2x1bW",
808
+ isAssertionEncrypted: true,
809
+ encPrivateKey: idpEncryptionKey,
810
+ encPrivateKeyPass: "g7hGcRmp8PxT5QeP2q9Ehf1bWe9zTALN",
811
+ },
812
+ spMetadata: {
813
+ binding: "post",
814
+ privateKey: spPrivateKey,
815
+ privateKeyPass: "VHOSp5RUiBcrsjrcAuXFwU1NKCkGA8px",
816
+ isAssertionEncrypted: true,
817
+ encPrivateKey: spEncryptionKey,
818
+ encPrivateKeyPass: "BXFNKpxrsjrCkGA8cAu5wUVHOSpci1RU",
819
+ },
820
+ identifierFormat:
821
+ "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress",
822
+ },
823
+ },
824
+ headers,
825
+ });
826
+
827
+ const spMetadataRes = await auth.api.spMetadata({
828
+ query: {
829
+ providerId: provider.providerId,
830
+ },
831
+ });
832
+ const spMetadataResResValue = await spMetadataRes.text();
833
+ expect(spMetadataRes.status).toBe(200);
834
+ expect(spMetadataResResValue).toBeDefined();
835
+ expect(spMetadataResResValue).toContain(
836
+ "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress",
837
+ );
838
+ expect(spMetadataResResValue).toContain(
839
+ "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST",
840
+ );
841
+ expect(spMetadataResResValue).toContain(
842
+ `<EntityDescriptor entityID="${issuer}"`,
843
+ );
844
+ expect(spMetadataResResValue).toContain(
845
+ `Location="${issuer}/api/sso/saml2/sp/acs"`,
846
+ );
847
+ });
785
848
  it("should initiate SAML login and handle response", async () => {
786
849
  const headers = await getAuthHeaders();
787
850
  const res = await authClient.signIn.email(testUser, {
@@ -805,7 +868,7 @@ describe("SAML SSO", async () => {
805
868
  privateKey: idpPrivateKey,
806
869
  privateKeyPass: "q9ALNhGT5EhfcRmp8Pg7e9zTQeP2x1bW",
807
870
  isAssertionEncrypted: true,
808
- encPrivateKey: idpEncyptionKey,
871
+ encPrivateKey: idpEncryptionKey,
809
872
  encPrivateKeyPass: "g7hGcRmp8PxT5QeP2q9Ehf1bWe9zTALN",
810
873
  },
811
874
  spMetadata: {
@@ -814,7 +877,7 @@ describe("SAML SSO", async () => {
814
877
  privateKey: spPrivateKey,
815
878
  privateKeyPass: "VHOSp5RUiBcrsjrcAuXFwU1NKCkGA8px",
816
879
  isAssertionEncrypted: true,
817
- encPrivateKey: spEncyptionKey,
880
+ encPrivateKey: spEncryptionKey,
818
881
  encPrivateKeyPass: "BXFNKpxrsjrCkGA8cAu5wUVHOSpci1RU",
819
882
  },
820
883
  identifierFormat:
package/tsconfig.json CHANGED
@@ -1,20 +1,14 @@
1
1
  {
2
+ "extends": "../../tsconfig.json",
2
3
  "compilerOptions": {
3
- "esModuleInterop": true,
4
- "skipLibCheck": true,
5
- "target": "es2022",
6
- "allowJs": true,
7
- "resolveJsonModule": true,
8
- "module": "ESNext",
9
- "noEmit": true,
10
- "moduleResolution": "Bundler",
11
- "moduleDetection": "force",
12
- "isolatedModules": true,
13
- "verbatimModuleSyntax": true,
14
- "strict": true,
15
- "noImplicitOverride": true,
16
- "noFallthroughCasesInSwitch": true
4
+ "rootDir": "./src",
5
+ "outDir": "./dist",
6
+ "lib": ["esnext", "dom", "dom.iterable"]
17
7
  },
18
- "exclude": ["node_modules", "dist"],
8
+ "references": [
9
+ {
10
+ "path": "../better-auth/tsconfig.json"
11
+ }
12
+ ],
19
13
  "include": ["src"]
20
14
  }