@mastra/auth-better-auth 0.0.0-agent-chat-ui-20260305212602

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/CHANGELOG.md ADDED
@@ -0,0 +1,124 @@
1
+ # @mastra/auth-better-auth
2
+
3
+ ## 0.0.0-agent-chat-ui-20260305212602
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [[`41e48c1`](https://github.com/mastra-ai/mastra/commit/41e48c198eee846478e60c02ec432c19d322a517), [`82469d3`](https://github.com/mastra-ai/mastra/commit/82469d3135d5a49dd8dc8feec0ff398b4e0225a0), [`33e2fd5`](https://github.com/mastra-ai/mastra/commit/33e2fd5088f83666df17401e2da68c943dbc0448), [`7ef6e2c`](https://github.com/mastra-ai/mastra/commit/7ef6e2c61be5a42e26f55d15b5902866fc76634f), [`b12d2a5`](https://github.com/mastra-ai/mastra/commit/b12d2a59a48be0477cabae66eb6cf0fc94a7d40d), [`fa37d39`](https://github.com/mastra-ai/mastra/commit/fa37d39910421feaf8847716292e3d65dd4f30c2), [`b12d2a5`](https://github.com/mastra-ai/mastra/commit/b12d2a59a48be0477cabae66eb6cf0fc94a7d40d), [`71c38bf`](https://github.com/mastra-ai/mastra/commit/71c38bf905905148ecd0e75c07c1f9825d299b76), [`f993c38`](https://github.com/mastra-ai/mastra/commit/f993c3848c97479b813231be872443bedeced6ab), [`f51849a`](https://github.com/mastra-ai/mastra/commit/f51849a568935122b5100b7ee69704e6d680cf7b), [`9bf3a0d`](https://github.com/mastra-ai/mastra/commit/9bf3a0dac602787925f1762f1f0387d7b4a59620), [`cafa045`](https://github.com/mastra-ai/mastra/commit/cafa0453c9de141ad50c09a13894622dffdd9978), [`1fd9ddb`](https://github.com/mastra-ai/mastra/commit/1fd9ddbb3fe83b281b12bd2e27e426ae86288266), [`6135ef4`](https://github.com/mastra-ai/mastra/commit/6135ef4f5288652bf45f616ec590607e4c95f443), [`d9d228c`](https://github.com/mastra-ai/mastra/commit/d9d228c0c6ae82ae6ce3b540a3a56b2b1c2b8d98), [`5576507`](https://github.com/mastra-ai/mastra/commit/55765071e360fb97e443aa0a91ccf7e1cd8d92aa), [`79d69c9`](https://github.com/mastra-ai/mastra/commit/79d69c9d5f842ff1c31352fb6026f04c1f6190f3), [`94f44b8`](https://github.com/mastra-ai/mastra/commit/94f44b827ce57b179e50f4916a84c0fa6e7f3b8c), [`13187db`](https://github.com/mastra-ai/mastra/commit/13187dbac880174232dedc5a501ff6c5d0fe59bc), [`2ae5311`](https://github.com/mastra-ai/mastra/commit/2ae531185fff66a80fa165c0999e3d801900e89d), [`6135ef4`](https://github.com/mastra-ai/mastra/commit/6135ef4f5288652bf45f616ec590607e4c95f443)]:
8
+ - @mastra/core@0.0.0-agent-chat-ui-20260305212602
9
+
10
+ ## 1.0.2
11
+
12
+ ### Patch Changes
13
+
14
+ - Expanded `@mastra/auth-better-auth` to implement the new auth interfaces (`IUserProvider`, `ISessionProvider`, `ICredentialsProvider`) from `@mastra/core/auth`. Adds support for username/password credential flows alongside the existing token-based authentication. ([#13163](https://github.com/mastra-ai/mastra/pull/13163))
15
+
16
+ - Updated dependencies [[`504fc8b`](https://github.com/mastra-ai/mastra/commit/504fc8b9d0ddab717577ad3bf9c95ea4bd5377bd), [`f9c150b`](https://github.com/mastra-ai/mastra/commit/f9c150b7595ad05ad9cc9a11098e2944361e8c22), [`88de7e8`](https://github.com/mastra-ai/mastra/commit/88de7e8dfe4b7e1951a9e441bb33136e705ce24e), [`edee4b3`](https://github.com/mastra-ai/mastra/commit/edee4b37dff0af515fc7cc0e8d71ee39e6a762f0), [`3790c75`](https://github.com/mastra-ai/mastra/commit/3790c7578cc6a47d854eb12d89e6b1912867fe29), [`e7a235b`](https://github.com/mastra-ai/mastra/commit/e7a235be6472e0c870ed6c791ddb17c492dc188b), [`d51d298`](https://github.com/mastra-ai/mastra/commit/d51d298953967aab1f58ec965b644d109214f085), [`6dbeeb9`](https://github.com/mastra-ai/mastra/commit/6dbeeb94a8b1eebb727300d1a98961f882180794), [`d5f0d8d`](https://github.com/mastra-ai/mastra/commit/d5f0d8d6a03e515ddaa9b5da19b7e44b8357b07b), [`09c3b18`](https://github.com/mastra-ai/mastra/commit/09c3b1802ff14e243a8a8baea327440bc8cc2e32), [`b896379`](https://github.com/mastra-ai/mastra/commit/b8963791c6afa79484645fcec596a201f936b9a2), [`85c84eb`](https://github.com/mastra-ai/mastra/commit/85c84ebb78aebfcba9d209c8e152b16d7a00cb71), [`a89272a`](https://github.com/mastra-ai/mastra/commit/a89272a5d71939b9fcd284e6a6dc1dd091a6bdcf), [`ee9c8df`](https://github.com/mastra-ai/mastra/commit/ee9c8df644f19d055af5f496bf4942705f5a47b7), [`77b4a25`](https://github.com/mastra-ai/mastra/commit/77b4a254e51907f8ff3a3ba95596a18e93ae4b35), [`276246e`](https://github.com/mastra-ai/mastra/commit/276246e0b9066a1ea48bbc70df84dbe528daaf99), [`08ecfdb`](https://github.com/mastra-ai/mastra/commit/08ecfdbdad6fb8285deef86a034bdf4a6047cfca), [`d5f628c`](https://github.com/mastra-ai/mastra/commit/d5f628ca86c6f6f3ff1035d52f635df32dd81cab), [`524c0f3`](https://github.com/mastra-ai/mastra/commit/524c0f3c434c3d9d18f66338dcef383d6161b59c), [`c18a0e9`](https://github.com/mastra-ai/mastra/commit/c18a0e9cef1e4ca004b2963d35e4cfc031971eac), [`4bd21ea`](https://github.com/mastra-ai/mastra/commit/4bd21ea43d44d0a0427414fc047577f9f0aa3bec), [`115a7a4`](https://github.com/mastra-ai/mastra/commit/115a7a47db5e9896fec12ae6507501adb9ec89bf), [`22a48ae`](https://github.com/mastra-ai/mastra/commit/22a48ae2513eb54d8d79dad361fddbca97a155e8), [`3c6ef79`](https://github.com/mastra-ai/mastra/commit/3c6ef798481e00d6d22563be2de98818fd4dd5e0), [`9311c17`](https://github.com/mastra-ai/mastra/commit/9311c17d7a0640d9c4da2e71b814dc67c57c6369), [`7edf78f`](https://github.com/mastra-ai/mastra/commit/7edf78f80422c43e84585f08ba11df0d4d0b73c5), [`1c4221c`](https://github.com/mastra-ai/mastra/commit/1c4221cf6032ec98d0e094d4ee11da3e48490d96), [`d25b9ea`](https://github.com/mastra-ai/mastra/commit/d25b9eabd400167255a97b690ffbc4ee4097ded5), [`fe1ce5c`](https://github.com/mastra-ai/mastra/commit/fe1ce5c9211c03d561606fda95cbfe7df1d9a9b5), [`b03c0e0`](https://github.com/mastra-ai/mastra/commit/b03c0e0389a799523929a458b0509c9e4244d562), [`0a8366b`](https://github.com/mastra-ai/mastra/commit/0a8366b0a692fcdde56c4d526e4cf03c502ae4ac), [`85664e9`](https://github.com/mastra-ai/mastra/commit/85664e9fd857320fbc245e301f764f45f66f32a3), [`bc79650`](https://github.com/mastra-ai/mastra/commit/bc796500c6e0334faa158a96077e3fb332274869), [`9257d01`](https://github.com/mastra-ai/mastra/commit/9257d01d1366d81f84c582fe02b5e200cf9621f4), [`3a3a59e`](https://github.com/mastra-ai/mastra/commit/3a3a59e8ffaa6a985fe3d9a126a3f5ade11a6724), [`3108d4e`](https://github.com/mastra-ai/mastra/commit/3108d4e649c9fddbf03253a6feeb388a5fa9fa5a), [`0c33b2c`](https://github.com/mastra-ai/mastra/commit/0c33b2c9db537f815e1c59e2c898ffce2e395a79), [`191e5bd`](https://github.com/mastra-ai/mastra/commit/191e5bd29b82f5bda35243945790da7bc7b695c2), [`f77cd94`](https://github.com/mastra-ai/mastra/commit/f77cd94c44eabed490384e7d19232a865e13214c), [`e8135c7`](https://github.com/mastra-ai/mastra/commit/e8135c7e300dac5040670eec7eab896ac6092e30), [`daca48f`](https://github.com/mastra-ai/mastra/commit/daca48f0fb17b7ae0b62a2ac40cf0e491b2fd0b7), [`257d14f`](https://github.com/mastra-ai/mastra/commit/257d14faca5931f2e4186fc165b6f0b1f915deee), [`352f25d`](https://github.com/mastra-ai/mastra/commit/352f25da316b24cdd5b410fd8dddf6a8b763da2a), [`93477d0`](https://github.com/mastra-ai/mastra/commit/93477d0769b8a13ea5ed73d508d967fb23eaeed9), [`31c78b3`](https://github.com/mastra-ai/mastra/commit/31c78b3eb28f58a8017f1dcc795c33214d87feac), [`0bc0720`](https://github.com/mastra-ai/mastra/commit/0bc07201095791858087cc56f353fcd65e87ab54), [`36516ac`](https://github.com/mastra-ai/mastra/commit/36516aca1021cbeb42e74751b46a2614101f37c8), [`e947652`](https://github.com/mastra-ai/mastra/commit/e9476527fdecb4449e54570e80dfaf8466901254), [`3c6ef79`](https://github.com/mastra-ai/mastra/commit/3c6ef798481e00d6d22563be2de98818fd4dd5e0), [`9257d01`](https://github.com/mastra-ai/mastra/commit/9257d01d1366d81f84c582fe02b5e200cf9621f4), [`ec248f6`](https://github.com/mastra-ai/mastra/commit/ec248f6b56e8a037c066c49b2178e2507471d988)]:
17
+ - @mastra/core@1.9.0
18
+
19
+ ## 1.0.2-alpha.0
20
+
21
+ ### Patch Changes
22
+
23
+ - Expanded `@mastra/auth-better-auth` to implement the new auth interfaces (`IUserProvider`, `ISessionProvider`, `ICredentialsProvider`) from `@mastra/core/auth`. Adds support for username/password credential flows alongside the existing token-based authentication. ([#13163](https://github.com/mastra-ai/mastra/pull/13163))
24
+
25
+ - Updated dependencies [[`504fc8b`](https://github.com/mastra-ai/mastra/commit/504fc8b9d0ddab717577ad3bf9c95ea4bd5377bd), [`f9c150b`](https://github.com/mastra-ai/mastra/commit/f9c150b7595ad05ad9cc9a11098e2944361e8c22), [`88de7e8`](https://github.com/mastra-ai/mastra/commit/88de7e8dfe4b7e1951a9e441bb33136e705ce24e), [`edee4b3`](https://github.com/mastra-ai/mastra/commit/edee4b37dff0af515fc7cc0e8d71ee39e6a762f0), [`3790c75`](https://github.com/mastra-ai/mastra/commit/3790c7578cc6a47d854eb12d89e6b1912867fe29), [`e7a235b`](https://github.com/mastra-ai/mastra/commit/e7a235be6472e0c870ed6c791ddb17c492dc188b), [`d51d298`](https://github.com/mastra-ai/mastra/commit/d51d298953967aab1f58ec965b644d109214f085), [`6dbeeb9`](https://github.com/mastra-ai/mastra/commit/6dbeeb94a8b1eebb727300d1a98961f882180794), [`d5f0d8d`](https://github.com/mastra-ai/mastra/commit/d5f0d8d6a03e515ddaa9b5da19b7e44b8357b07b), [`09c3b18`](https://github.com/mastra-ai/mastra/commit/09c3b1802ff14e243a8a8baea327440bc8cc2e32), [`b896379`](https://github.com/mastra-ai/mastra/commit/b8963791c6afa79484645fcec596a201f936b9a2), [`85c84eb`](https://github.com/mastra-ai/mastra/commit/85c84ebb78aebfcba9d209c8e152b16d7a00cb71), [`a89272a`](https://github.com/mastra-ai/mastra/commit/a89272a5d71939b9fcd284e6a6dc1dd091a6bdcf), [`ee9c8df`](https://github.com/mastra-ai/mastra/commit/ee9c8df644f19d055af5f496bf4942705f5a47b7), [`77b4a25`](https://github.com/mastra-ai/mastra/commit/77b4a254e51907f8ff3a3ba95596a18e93ae4b35), [`276246e`](https://github.com/mastra-ai/mastra/commit/276246e0b9066a1ea48bbc70df84dbe528daaf99), [`08ecfdb`](https://github.com/mastra-ai/mastra/commit/08ecfdbdad6fb8285deef86a034bdf4a6047cfca), [`d5f628c`](https://github.com/mastra-ai/mastra/commit/d5f628ca86c6f6f3ff1035d52f635df32dd81cab), [`524c0f3`](https://github.com/mastra-ai/mastra/commit/524c0f3c434c3d9d18f66338dcef383d6161b59c), [`c18a0e9`](https://github.com/mastra-ai/mastra/commit/c18a0e9cef1e4ca004b2963d35e4cfc031971eac), [`4bd21ea`](https://github.com/mastra-ai/mastra/commit/4bd21ea43d44d0a0427414fc047577f9f0aa3bec), [`115a7a4`](https://github.com/mastra-ai/mastra/commit/115a7a47db5e9896fec12ae6507501adb9ec89bf), [`22a48ae`](https://github.com/mastra-ai/mastra/commit/22a48ae2513eb54d8d79dad361fddbca97a155e8), [`3c6ef79`](https://github.com/mastra-ai/mastra/commit/3c6ef798481e00d6d22563be2de98818fd4dd5e0), [`9311c17`](https://github.com/mastra-ai/mastra/commit/9311c17d7a0640d9c4da2e71b814dc67c57c6369), [`7edf78f`](https://github.com/mastra-ai/mastra/commit/7edf78f80422c43e84585f08ba11df0d4d0b73c5), [`1c4221c`](https://github.com/mastra-ai/mastra/commit/1c4221cf6032ec98d0e094d4ee11da3e48490d96), [`d25b9ea`](https://github.com/mastra-ai/mastra/commit/d25b9eabd400167255a97b690ffbc4ee4097ded5), [`fe1ce5c`](https://github.com/mastra-ai/mastra/commit/fe1ce5c9211c03d561606fda95cbfe7df1d9a9b5), [`b03c0e0`](https://github.com/mastra-ai/mastra/commit/b03c0e0389a799523929a458b0509c9e4244d562), [`0a8366b`](https://github.com/mastra-ai/mastra/commit/0a8366b0a692fcdde56c4d526e4cf03c502ae4ac), [`85664e9`](https://github.com/mastra-ai/mastra/commit/85664e9fd857320fbc245e301f764f45f66f32a3), [`bc79650`](https://github.com/mastra-ai/mastra/commit/bc796500c6e0334faa158a96077e3fb332274869), [`9257d01`](https://github.com/mastra-ai/mastra/commit/9257d01d1366d81f84c582fe02b5e200cf9621f4), [`3a3a59e`](https://github.com/mastra-ai/mastra/commit/3a3a59e8ffaa6a985fe3d9a126a3f5ade11a6724), [`3108d4e`](https://github.com/mastra-ai/mastra/commit/3108d4e649c9fddbf03253a6feeb388a5fa9fa5a), [`0c33b2c`](https://github.com/mastra-ai/mastra/commit/0c33b2c9db537f815e1c59e2c898ffce2e395a79), [`191e5bd`](https://github.com/mastra-ai/mastra/commit/191e5bd29b82f5bda35243945790da7bc7b695c2), [`f77cd94`](https://github.com/mastra-ai/mastra/commit/f77cd94c44eabed490384e7d19232a865e13214c), [`e8135c7`](https://github.com/mastra-ai/mastra/commit/e8135c7e300dac5040670eec7eab896ac6092e30), [`daca48f`](https://github.com/mastra-ai/mastra/commit/daca48f0fb17b7ae0b62a2ac40cf0e491b2fd0b7), [`257d14f`](https://github.com/mastra-ai/mastra/commit/257d14faca5931f2e4186fc165b6f0b1f915deee), [`352f25d`](https://github.com/mastra-ai/mastra/commit/352f25da316b24cdd5b410fd8dddf6a8b763da2a), [`93477d0`](https://github.com/mastra-ai/mastra/commit/93477d0769b8a13ea5ed73d508d967fb23eaeed9), [`31c78b3`](https://github.com/mastra-ai/mastra/commit/31c78b3eb28f58a8017f1dcc795c33214d87feac), [`0bc0720`](https://github.com/mastra-ai/mastra/commit/0bc07201095791858087cc56f353fcd65e87ab54), [`36516ac`](https://github.com/mastra-ai/mastra/commit/36516aca1021cbeb42e74751b46a2614101f37c8), [`e947652`](https://github.com/mastra-ai/mastra/commit/e9476527fdecb4449e54570e80dfaf8466901254), [`3c6ef79`](https://github.com/mastra-ai/mastra/commit/3c6ef798481e00d6d22563be2de98818fd4dd5e0), [`9257d01`](https://github.com/mastra-ai/mastra/commit/9257d01d1366d81f84c582fe02b5e200cf9621f4), [`ec248f6`](https://github.com/mastra-ai/mastra/commit/ec248f6b56e8a037c066c49b2178e2507471d988)]:
26
+ - @mastra/core@1.9.0-alpha.0
27
+
28
+ ## 1.0.1
29
+
30
+ ### Patch Changes
31
+
32
+ - dependencies updates: ([#12964](https://github.com/mastra-ai/mastra/pull/12964))
33
+ - Updated dependency [`better-auth@^1.4.18` ↗︎](https://www.npmjs.com/package/better-auth/v/1.4.18) (from `^1.4.5`, in `dependencies`)
34
+
35
+ ## 1.0.1-alpha.0
36
+
37
+ ### Patch Changes
38
+
39
+ - dependencies updates: ([#12964](https://github.com/mastra-ai/mastra/pull/12964))
40
+ - Updated dependency [`better-auth@^1.4.18` ↗︎](https://www.npmjs.com/package/better-auth/v/1.4.18) (from `^1.4.5`, in `dependencies`)
41
+
42
+ ## 1.0.0
43
+
44
+ ### Minor Changes
45
+
46
+ - Add Better Auth authentication provider ([#10658](https://github.com/mastra-ai/mastra/pull/10658))
47
+
48
+ Adds a new authentication provider for Better Auth, a self-hosted, open-source authentication framework.
49
+
50
+ ```typescript
51
+ import { betterAuth } from 'better-auth';
52
+ import { MastraAuthBetterAuth } from '@mastra/auth-better-auth';
53
+ import { Mastra } from '@mastra/core';
54
+
55
+ // Create your Better Auth instance
56
+ const auth = betterAuth({
57
+ database: {
58
+ provider: 'postgresql',
59
+ url: process.env.DATABASE_URL!,
60
+ },
61
+ emailAndPassword: {
62
+ enabled: true,
63
+ },
64
+ });
65
+
66
+ // Create the Mastra auth provider
67
+ const mastraAuth = new MastraAuthBetterAuth({
68
+ auth,
69
+ });
70
+
71
+ // Use with Mastra
72
+ const mastra = new Mastra({
73
+ server: {
74
+ auth: mastraAuth,
75
+ },
76
+ });
77
+ ```
78
+
79
+ ## 1.0.0-beta.2
80
+
81
+ ### Minor Changes
82
+
83
+ - Add Better Auth authentication provider ([#10658](https://github.com/mastra-ai/mastra/pull/10658))
84
+
85
+ Adds a new authentication provider for Better Auth, a self-hosted, open-source authentication framework.
86
+
87
+ ```typescript
88
+ import { betterAuth } from 'better-auth';
89
+ import { MastraAuthBetterAuth } from '@mastra/auth-better-auth';
90
+ import { Mastra } from '@mastra/core';
91
+
92
+ // Create your Better Auth instance
93
+ const auth = betterAuth({
94
+ database: {
95
+ provider: 'postgresql',
96
+ url: process.env.DATABASE_URL!,
97
+ },
98
+ emailAndPassword: {
99
+ enabled: true,
100
+ },
101
+ });
102
+
103
+ // Create the Mastra auth provider
104
+ const mastraAuth = new MastraAuthBetterAuth({
105
+ auth,
106
+ });
107
+
108
+ // Use with Mastra
109
+ const mastra = new Mastra({
110
+ server: {
111
+ auth: mastraAuth,
112
+ },
113
+ });
114
+ ```
115
+
116
+ ## 1.0.0-beta.1
117
+
118
+ ### Major Changes
119
+
120
+ - Initial release of Better Auth integration for Mastra
121
+ - Self-hosted authentication provider using Better Auth
122
+ - Support for session-based authentication
123
+ - Custom authorization logic support
124
+ - Route configuration for public/protected paths
package/LICENSE.md ADDED
@@ -0,0 +1,30 @@
1
+ Portions of this software are licensed as follows:
2
+
3
+ - All content that resides under any directory named "ee/" within this
4
+ repository, including but not limited to:
5
+ - `packages/core/src/auth/ee/`
6
+ - `packages/server/src/server/auth/ee/`
7
+ is licensed under the license defined in `ee/LICENSE`.
8
+
9
+ - All third-party components incorporated into the Mastra Software are
10
+ licensed under the original license provided by the owner of the
11
+ applicable component.
12
+
13
+ - Content outside of the above-mentioned directories or restrictions is
14
+ available under the "Apache License 2.0" as defined below.
15
+
16
+ # Apache License 2.0
17
+
18
+ Copyright (c) 2025 Kepler Software, Inc.
19
+
20
+ Licensed under the Apache License, Version 2.0 (the "License");
21
+ you may not use this file except in compliance with the License.
22
+ You may obtain a copy of the License at
23
+
24
+ http://www.apache.org/licenses/LICENSE-2.0
25
+
26
+ Unless required by applicable law or agreed to in writing, software
27
+ distributed under the License is distributed on an "AS IS" BASIS,
28
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
29
+ See the License for the specific language governing permissions and
30
+ limitations under the License.
package/README.md ADDED
@@ -0,0 +1,107 @@
1
+ # @mastra/auth-better-auth
2
+
3
+ Better Auth integration for Mastra - a self-hosted, open-source authentication solution.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @mastra/auth-better-auth better-auth
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```typescript
14
+ import { betterAuth } from 'better-auth';
15
+ import { MastraAuthBetterAuth } from '@mastra/auth-better-auth';
16
+ import { Mastra } from '@mastra/core';
17
+
18
+ // Create your Better Auth instance
19
+ const auth = betterAuth({
20
+ database: {
21
+ provider: 'postgresql',
22
+ url: process.env.DATABASE_URL!,
23
+ },
24
+ emailAndPassword: {
25
+ enabled: true,
26
+ },
27
+ });
28
+
29
+ // Create the Mastra auth provider
30
+ const mastraAuth = new MastraAuthBetterAuth({
31
+ auth,
32
+ });
33
+
34
+ // Use with Mastra
35
+ const mastra = new Mastra({
36
+ server: {
37
+ auth: mastraAuth,
38
+ },
39
+ });
40
+ ```
41
+
42
+ ## Configuration Options
43
+
44
+ | Option | Type | Required | Description |
45
+ | --------------- | ------------------------------------- | -------- | ------------------------------------------------------------ |
46
+ | `auth` | `Auth` | Yes | Your Better Auth instance created via `betterAuth({ ... })` |
47
+ | `name` | `string` | No | Custom name for the auth provider (default: `'better-auth'`) |
48
+ | `authorizeUser` | `(user, request) => Promise<boolean>` | No | Custom authorization logic |
49
+ | `public` | `string[]` | No | Public routes that don't require authentication |
50
+ | `protected` | `string[]` | No | Protected routes that require authentication |
51
+
52
+ ## Custom Authorization
53
+
54
+ You can provide custom authorization logic:
55
+
56
+ ```typescript
57
+ const mastraAuth = new MastraAuthBetterAuth({
58
+ auth,
59
+ async authorizeUser(user) {
60
+ // Only allow verified emails
61
+ return user?.user?.emailVerified === true;
62
+ },
63
+ });
64
+ ```
65
+
66
+ ## Role-Based Access Control
67
+
68
+ ```typescript
69
+ const mastraAuth = new MastraAuthBetterAuth({
70
+ auth,
71
+ async authorizeUser(user) {
72
+ // Check for admin role (assuming you have a role field)
73
+ const userWithRole = user?.user as any;
74
+ return userWithRole?.role === 'admin';
75
+ },
76
+ });
77
+ ```
78
+
79
+ ## Route Configuration
80
+
81
+ ```typescript
82
+ const mastraAuth = new MastraAuthBetterAuth({
83
+ auth,
84
+ public: ['/health', '/api/status'],
85
+ protected: ['/api/*', '/admin/*'],
86
+ });
87
+ ```
88
+
89
+ ## Why Better Auth?
90
+
91
+ Better Auth is a self-hosted, open-source authentication framework that gives you:
92
+
93
+ - **Full control** over your authentication system
94
+ - **No vendor lock-in** - host it yourself
95
+ - **Flexible** - works with various databases and providers
96
+ - **TypeScript-first** - full type safety
97
+ - **Plugin system** - extend with OAuth, 2FA, organizations, etc.
98
+
99
+ ## Resources
100
+
101
+ - [Better Auth Documentation](https://better-auth.com)
102
+ - [Mastra Documentation](https://mastra.ai/docs)
103
+ - [GitHub Repository](https://github.com/mastra-ai/mastra)
104
+
105
+ ## License
106
+
107
+ Apache-2.0
package/dist/index.cjs ADDED
@@ -0,0 +1,247 @@
1
+ 'use strict';
2
+
3
+ var server = require('@mastra/core/server');
4
+
5
+ // src/index.ts
6
+ function mapBetterAuthUserToEEUser(user) {
7
+ return {
8
+ id: user.id,
9
+ email: user.email,
10
+ name: user.name,
11
+ avatarUrl: user.image ?? void 0,
12
+ metadata: {
13
+ emailVerified: user.emailVerified,
14
+ createdAt: user.createdAt,
15
+ updatedAt: user.updatedAt
16
+ }
17
+ };
18
+ }
19
+ var MastraAuthBetterAuth = class extends server.MastraAuthProvider {
20
+ auth;
21
+ signUpEnabledConfig;
22
+ sessionCookieName;
23
+ constructor(options) {
24
+ super({ name: options?.name ?? "better-auth" });
25
+ if (!options.auth) {
26
+ throw new Error(
27
+ "Better Auth instance is required. Please provide the auth option with your Better Auth instance created via betterAuth({ ... })"
28
+ );
29
+ }
30
+ this.auth = options.auth;
31
+ this.signUpEnabledConfig = options.signUpEnabled ?? true;
32
+ const authWithOptions = this.auth;
33
+ const prefix = authWithOptions.options?.advanced?.cookiePrefix ?? "better-auth";
34
+ this.sessionCookieName = `${prefix}.session_token`;
35
+ this.registerOptions(options);
36
+ }
37
+ /**
38
+ * Check if sign-up is enabled.
39
+ * Implements ICredentialsProvider.isSignUpEnabled.
40
+ */
41
+ isSignUpEnabled() {
42
+ return this.signUpEnabledConfig;
43
+ }
44
+ // ============================================
45
+ // IUserProvider implementation (EE capability)
46
+ // License check happens in buildCapabilities()
47
+ // ============================================
48
+ /**
49
+ * Get current user from request.
50
+ * Implements IUserProvider for EE user awareness in Studio.
51
+ *
52
+ * @param request - Incoming HTTP request
53
+ * @returns EE User object or null if not authenticated
54
+ */
55
+ async getCurrentUser(request) {
56
+ try {
57
+ const result = await this.auth.api.getSession({
58
+ headers: request.headers
59
+ });
60
+ if (!result?.user) return null;
61
+ return mapBetterAuthUserToEEUser(result.user);
62
+ } catch {
63
+ return null;
64
+ }
65
+ }
66
+ /**
67
+ * Get user by ID.
68
+ * Implements IUserProvider for EE user awareness.
69
+ *
70
+ * Note: Better Auth doesn't expose a direct getUser API.
71
+ * For full functionality, you may need to implement this using
72
+ * direct database access in a subclass.
73
+ *
74
+ * @param userId - User identifier
75
+ * @returns EE User object or null if not found
76
+ */
77
+ async getUser(_userId) {
78
+ console.warn(
79
+ "[MastraAuthBetterAuth] getUser() requires direct database access. Override this method in a subclass for full user lookup support."
80
+ );
81
+ return null;
82
+ }
83
+ /**
84
+ * Get URL to user's profile page.
85
+ * Optional IUserProvider method.
86
+ */
87
+ getUserProfileUrl(user) {
88
+ return `/profile/${user.id}`;
89
+ }
90
+ /**
91
+ * Authenticate a bearer token by verifying the session with Better Auth.
92
+ *
93
+ * This method extracts the session from the request headers using
94
+ * Better Auth's `api.getSession()` endpoint.
95
+ *
96
+ * @param token - The bearer token (session token) to authenticate
97
+ * @param request - The Hono request object containing headers
98
+ * @returns The authenticated user and session, or null if authentication fails
99
+ */
100
+ async authenticateToken(token, request) {
101
+ try {
102
+ const headers = new Headers();
103
+ const rawRequest = "raw" in request ? request.raw : request;
104
+ const cookieHeader = rawRequest.headers.get("Cookie");
105
+ if (cookieHeader) {
106
+ headers.set("Cookie", cookieHeader);
107
+ }
108
+ const hasSessionCookie = !!cookieHeader?.split(";").some((pair) => {
109
+ const [key] = pair.trim().split("=");
110
+ return key?.trim() === this.sessionCookieName;
111
+ });
112
+ if (token && !hasSessionCookie) {
113
+ const existingCookies = cookieHeader ? `${cookieHeader}; ` : "";
114
+ headers.set("Cookie", `${existingCookies}${this.sessionCookieName}=${token}`);
115
+ }
116
+ const result = await this.auth.api.getSession({
117
+ headers
118
+ });
119
+ if (!result || !result.session || !result.user) {
120
+ return null;
121
+ }
122
+ return {
123
+ session: result.session,
124
+ user: result.user
125
+ };
126
+ } catch {
127
+ return null;
128
+ }
129
+ }
130
+ /**
131
+ * Authorize a user for access.
132
+ *
133
+ * By default, any authenticated user with a valid session is authorized.
134
+ * You can override this behavior by providing a custom `authorizeUser` function
135
+ * in the constructor options.
136
+ *
137
+ * @param user - The authenticated user and session
138
+ * @returns True if the user is authorized, false otherwise
139
+ */
140
+ async authorizeUser(user) {
141
+ return !!user?.session?.id && !!user?.user?.id;
142
+ }
143
+ // ============================================
144
+ // ICredentialsProvider implementation (EE capability)
145
+ // License check happens in buildCapabilities()
146
+ // ============================================
147
+ /**
148
+ * Sign in with email and password.
149
+ * Implements ICredentialsProvider for EE credentials auth.
150
+ *
151
+ * @param email - User email
152
+ * @param password - User password
153
+ * @param request - Incoming HTTP request
154
+ * @returns Result with user and session cookies
155
+ * @throws Error if credentials are invalid
156
+ */
157
+ async signIn(email, password, request) {
158
+ const headers = request?.headers ?? new Headers();
159
+ const response = await this.auth.api.signInEmail({
160
+ body: { email, password },
161
+ headers,
162
+ asResponse: true
163
+ });
164
+ if (!response.ok) {
165
+ const errorData = await response.json().catch(() => ({}));
166
+ throw new Error(errorData.message || "Invalid email or password");
167
+ }
168
+ const result = await response.json();
169
+ if (!result?.user) {
170
+ throw new Error("Invalid email or password");
171
+ }
172
+ const cookies = [];
173
+ const setCookieHeader = response.headers.get("set-cookie");
174
+ if (setCookieHeader) {
175
+ cookies.push(...setCookieHeader.split(/,(?=\s*\w+=)/));
176
+ }
177
+ return {
178
+ user: mapBetterAuthUserToEEUser(result.user),
179
+ token: result.token ?? void 0,
180
+ cookies
181
+ };
182
+ }
183
+ /**
184
+ * Sign up with email and password.
185
+ * Implements ICredentialsProvider for EE credentials auth.
186
+ *
187
+ * @param email - User email
188
+ * @param password - User password
189
+ * @param name - Optional display name
190
+ * @param request - Incoming HTTP request
191
+ * @returns Result with new user and session cookies
192
+ * @throws Error if sign up fails
193
+ */
194
+ async signUp(email, password, name, request) {
195
+ const displayName = name ?? email.split("@")[0] ?? "User";
196
+ const headers = request?.headers ?? new Headers();
197
+ const response = await this.auth.api.signUpEmail({
198
+ body: { email, password, name: displayName },
199
+ headers,
200
+ asResponse: true
201
+ });
202
+ if (!response.ok) {
203
+ const errorData = await response.json().catch(() => ({}));
204
+ throw new Error(errorData.message || "Failed to create account");
205
+ }
206
+ const result = await response.json();
207
+ if (!result?.user) {
208
+ throw new Error("Failed to create account");
209
+ }
210
+ const cookies = [];
211
+ const setCookieHeader = response.headers.get("set-cookie");
212
+ if (setCookieHeader) {
213
+ cookies.push(...setCookieHeader.split(/,(?=\s*\w+=)/));
214
+ }
215
+ return {
216
+ user: mapBetterAuthUserToEEUser(result.user),
217
+ token: result.token ?? void 0,
218
+ cookies
219
+ };
220
+ }
221
+ /**
222
+ * Get the underlying Better Auth instance.
223
+ * Useful for accessing Better Auth APIs directly.
224
+ */
225
+ getAuth() {
226
+ return this.auth;
227
+ }
228
+ /**
229
+ * Get headers to clear the session cookies on logout.
230
+ * Partial ISessionProvider implementation for logout support.
231
+ *
232
+ * Clears Better Auth's default session cookies.
233
+ */
234
+ getClearSessionHeaders() {
235
+ const cookies = [
236
+ `${this.sessionCookieName}=; Path=/; HttpOnly; SameSite=Lax; Max-Age=0`,
237
+ `${this.sessionCookieName}_sig=; Path=/; HttpOnly; SameSite=Lax; Max-Age=0`
238
+ ];
239
+ return {
240
+ "Set-Cookie": cookies.join(", ")
241
+ };
242
+ }
243
+ };
244
+
245
+ exports.MastraAuthBetterAuth = MastraAuthBetterAuth;
246
+ //# sourceMappingURL=index.cjs.map
247
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"names":["MastraAuthProvider"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { IUserProvider, ICredentialsProvider, CredentialsResult } from '@mastra/core/auth';\nimport type { EEUser } from '@mastra/core/auth/ee';\nimport type { MastraAuthProviderOptions } from '@mastra/core/server';\nimport { MastraAuthProvider } from '@mastra/core/server';\n\nimport type { Auth, Session, User } from 'better-auth';\nimport type { HonoRequest } from 'hono';\n\n/**\n * User type returned by Better Auth session verification.\n * Used internally for authentication token verification.\n */\nexport interface BetterAuthUser {\n session: Session;\n user: User;\n}\n\n/**\n * Maps Better Auth User to EE User format.\n */\nfunction mapBetterAuthUserToEEUser(user: User): EEUser {\n return {\n id: user.id,\n email: user.email,\n name: user.name,\n avatarUrl: user.image ?? undefined,\n metadata: {\n emailVerified: user.emailVerified,\n createdAt: user.createdAt,\n updatedAt: user.updatedAt,\n },\n };\n}\n\ninterface MastraAuthBetterAuthOptions extends MastraAuthProviderOptions<BetterAuthUser> {\n /**\n * The Better Auth instance to use for authentication.\n * This should be the result of calling `betterAuth({ ... })`.\n */\n auth: Auth;\n\n /**\n * Whether to allow new user registration via sign-up.\n * Set to false to disable public registration.\n * @default true\n */\n signUpEnabled?: boolean;\n}\n\n/**\n * Mastra authentication provider for Better Auth.\n *\n * Better Auth is a self-hosted, open-source authentication framework\n * that gives you full control over your authentication system.\n *\n * @example\n * ```typescript\n * import { betterAuth } from 'better-auth';\n * import { MastraAuthBetterAuth } from '@mastra/auth-better-auth';\n *\n * // Create your Better Auth instance\n * const auth = betterAuth({\n * database: {\n * provider: 'postgresql',\n * url: process.env.DATABASE_URL!,\n * },\n * emailAndPassword: {\n * enabled: true,\n * },\n * });\n *\n * // Create the Mastra auth provider\n * const mastraAuth = new MastraAuthBetterAuth({\n * auth,\n * });\n *\n * // Use with Mastra\n * const mastra = new Mastra({\n * server: {\n * auth: mastraAuth,\n * },\n * });\n * ```\n *\n * @see https://better-auth.com for Better Auth documentation\n */\nexport class MastraAuthBetterAuth\n extends MastraAuthProvider<BetterAuthUser>\n implements IUserProvider<EEUser>, ICredentialsProvider<EEUser>\n{\n protected auth: Auth;\n protected signUpEnabledConfig: boolean;\n public sessionCookieName: string;\n\n constructor(options: MastraAuthBetterAuthOptions) {\n super({ name: options?.name ?? 'better-auth' });\n\n if (!options.auth) {\n throw new Error(\n 'Better Auth instance is required. Please provide the auth option with your Better Auth instance created via betterAuth({ ... })',\n );\n }\n\n this.auth = options.auth;\n this.signUpEnabledConfig = options.signUpEnabled ?? true;\n\n // Derive the session cookie name from Better Auth's cookiePrefix option\n const authWithOptions = this.auth as unknown as { options?: { advanced?: { cookiePrefix?: string } } };\n const prefix = authWithOptions.options?.advanced?.cookiePrefix ?? 'better-auth';\n this.sessionCookieName = `${prefix}.session_token`;\n\n this.registerOptions(options);\n }\n\n /**\n * Check if sign-up is enabled.\n * Implements ICredentialsProvider.isSignUpEnabled.\n */\n isSignUpEnabled(): boolean {\n return this.signUpEnabledConfig;\n }\n\n // ============================================\n // IUserProvider implementation (EE capability)\n // License check happens in buildCapabilities()\n // ============================================\n\n /**\n * Get current user from request.\n * Implements IUserProvider for EE user awareness in Studio.\n *\n * @param request - Incoming HTTP request\n * @returns EE User object or null if not authenticated\n */\n async getCurrentUser(request: Request): Promise<EEUser | null> {\n try {\n const result = await this.auth.api.getSession({\n headers: request.headers,\n });\n\n if (!result?.user) return null;\n return mapBetterAuthUserToEEUser(result.user);\n } catch {\n return null;\n }\n }\n\n /**\n * Get user by ID.\n * Implements IUserProvider for EE user awareness.\n *\n * Note: Better Auth doesn't expose a direct getUser API.\n * For full functionality, you may need to implement this using\n * direct database access in a subclass.\n *\n * @param userId - User identifier\n * @returns EE User object or null if not found\n */\n async getUser(_userId: string): Promise<EEUser | null> {\n // Better Auth doesn't have a direct getUser API\n // Users can override this method with their own implementation\n // that queries the database directly\n console.warn(\n '[MastraAuthBetterAuth] getUser() requires direct database access. ' +\n 'Override this method in a subclass for full user lookup support.',\n );\n return null;\n }\n\n /**\n * Get URL to user's profile page.\n * Optional IUserProvider method.\n */\n getUserProfileUrl(user: EEUser): string {\n return `/profile/${user.id}`;\n }\n\n /**\n * Authenticate a bearer token by verifying the session with Better Auth.\n *\n * This method extracts the session from the request headers using\n * Better Auth's `api.getSession()` endpoint.\n *\n * @param token - The bearer token (session token) to authenticate\n * @param request - The Hono request object containing headers\n * @returns The authenticated user and session, or null if authentication fails\n */\n async authenticateToken(token: string, request: HonoRequest): Promise<BetterAuthUser | null> {\n try {\n // Better Auth's api.getSession() reads session tokens from the Cookie header\n const headers = new Headers();\n\n // The auth middleware may pass a raw Request (c.req.raw) instead of HonoRequest,\n // so unwrap via 'raw' property detection and use the standard Web API.\n const rawRequest: Request = 'raw' in request ? (request as any).raw : (request as unknown as Request);\n\n const cookieHeader = rawRequest.headers.get('Cookie');\n if (cookieHeader) {\n headers.set('Cookie', cookieHeader);\n }\n\n // Convert Bearer token to a session cookie if not already present.\n // better-auth ignores the Authorization header — it only reads from Cookie.\n const hasSessionCookie = !!cookieHeader?.split(';').some(pair => {\n const [key] = pair.trim().split('=');\n return key?.trim() === this.sessionCookieName;\n });\n if (token && !hasSessionCookie) {\n const existingCookies = cookieHeader ? `${cookieHeader}; ` : '';\n headers.set('Cookie', `${existingCookies}${this.sessionCookieName}=${token}`);\n }\n\n const result = await this.auth.api.getSession({\n headers,\n });\n\n if (!result || !result.session || !result.user) {\n return null;\n }\n\n return {\n session: result.session,\n user: result.user,\n };\n } catch {\n return null;\n }\n }\n\n /**\n * Authorize a user for access.\n *\n * By default, any authenticated user with a valid session is authorized.\n * You can override this behavior by providing a custom `authorizeUser` function\n * in the constructor options.\n *\n * @param user - The authenticated user and session\n * @returns True if the user is authorized, false otherwise\n */\n async authorizeUser(user: BetterAuthUser): Promise<boolean> {\n // By default, any authenticated user with a valid session is authorized\n return !!user?.session?.id && !!user?.user?.id;\n }\n\n // ============================================\n // ICredentialsProvider implementation (EE capability)\n // License check happens in buildCapabilities()\n // ============================================\n\n /**\n * Sign in with email and password.\n * Implements ICredentialsProvider for EE credentials auth.\n *\n * @param email - User email\n * @param password - User password\n * @param request - Incoming HTTP request\n * @returns Result with user and session cookies\n * @throws Error if credentials are invalid\n */\n async signIn(email: string, password: string, request: Request): Promise<CredentialsResult<EEUser>> {\n const headers = request?.headers ?? new Headers();\n\n // Use asResponse: true to get the full response with Set-Cookie headers\n const response = await this.auth.api.signInEmail({\n body: { email, password },\n headers,\n asResponse: true,\n });\n\n if (!response.ok) {\n const errorData = (await response.json().catch(() => ({}))) as { message?: string };\n throw new Error(errorData.message || 'Invalid email or password');\n }\n\n const result = (await response.json()) as { user?: User; token?: string | null };\n\n if (!result?.user) {\n throw new Error('Invalid email or password');\n }\n\n // Extract Set-Cookie headers from Better Auth response\n const cookies: string[] = [];\n const setCookieHeader = response.headers.get('set-cookie');\n if (setCookieHeader) {\n // Split multiple cookies (they may be comma-separated or in multiple headers)\n cookies.push(...setCookieHeader.split(/,(?=\\s*\\w+=)/));\n }\n\n return {\n user: mapBetterAuthUserToEEUser(result.user),\n token: result.token ?? undefined,\n cookies,\n };\n }\n\n /**\n * Sign up with email and password.\n * Implements ICredentialsProvider for EE credentials auth.\n *\n * @param email - User email\n * @param password - User password\n * @param name - Optional display name\n * @param request - Incoming HTTP request\n * @returns Result with new user and session cookies\n * @throws Error if sign up fails\n */\n async signUp(\n email: string,\n password: string,\n name: string | undefined,\n request: Request,\n ): Promise<CredentialsResult<EEUser>> {\n const displayName = name ?? email.split('@')[0] ?? 'User';\n const headers = request?.headers ?? new Headers();\n\n // Use asResponse: true to get the full response with Set-Cookie headers\n const response = await this.auth.api.signUpEmail({\n body: { email, password, name: displayName },\n headers,\n asResponse: true,\n });\n\n if (!response.ok) {\n const errorData = (await response.json().catch(() => ({}))) as { message?: string };\n throw new Error(errorData.message || 'Failed to create account');\n }\n\n const result = (await response.json()) as { user?: User; token?: string | null };\n\n if (!result?.user) {\n throw new Error('Failed to create account');\n }\n\n // Extract Set-Cookie headers from Better Auth response\n const cookies: string[] = [];\n const setCookieHeader = response.headers.get('set-cookie');\n if (setCookieHeader) {\n // Split multiple cookies (they may be comma-separated or in multiple headers)\n cookies.push(...setCookieHeader.split(/,(?=\\s*\\w+=)/));\n }\n\n return {\n user: mapBetterAuthUserToEEUser(result.user),\n token: result.token ?? undefined,\n cookies,\n };\n }\n\n /**\n * Get the underlying Better Auth instance.\n * Useful for accessing Better Auth APIs directly.\n */\n getAuth(): Auth {\n return this.auth;\n }\n\n /**\n * Get headers to clear the session cookies on logout.\n * Partial ISessionProvider implementation for logout support.\n *\n * Clears Better Auth's default session cookies.\n */\n getClearSessionHeaders(): Record<string, string> {\n // Clear both the session token and its signature cookie\n const cookies = [\n `${this.sessionCookieName}=; Path=/; HttpOnly; SameSite=Lax; Max-Age=0`,\n `${this.sessionCookieName}_sig=; Path=/; HttpOnly; SameSite=Lax; Max-Age=0`,\n ];\n return {\n 'Set-Cookie': cookies.join(', '),\n };\n }\n}\n"]}
@@ -0,0 +1,159 @@
1
+ import type { IUserProvider, ICredentialsProvider, CredentialsResult } from '@mastra/core/auth';
2
+ import type { EEUser } from '@mastra/core/auth/ee';
3
+ import type { MastraAuthProviderOptions } from '@mastra/core/server';
4
+ import { MastraAuthProvider } from '@mastra/core/server';
5
+ import type { Auth, Session, User } from 'better-auth';
6
+ import type { HonoRequest } from 'hono';
7
+ /**
8
+ * User type returned by Better Auth session verification.
9
+ * Used internally for authentication token verification.
10
+ */
11
+ export interface BetterAuthUser {
12
+ session: Session;
13
+ user: User;
14
+ }
15
+ interface MastraAuthBetterAuthOptions extends MastraAuthProviderOptions<BetterAuthUser> {
16
+ /**
17
+ * The Better Auth instance to use for authentication.
18
+ * This should be the result of calling `betterAuth({ ... })`.
19
+ */
20
+ auth: Auth;
21
+ /**
22
+ * Whether to allow new user registration via sign-up.
23
+ * Set to false to disable public registration.
24
+ * @default true
25
+ */
26
+ signUpEnabled?: boolean;
27
+ }
28
+ /**
29
+ * Mastra authentication provider for Better Auth.
30
+ *
31
+ * Better Auth is a self-hosted, open-source authentication framework
32
+ * that gives you full control over your authentication system.
33
+ *
34
+ * @example
35
+ * ```typescript
36
+ * import { betterAuth } from 'better-auth';
37
+ * import { MastraAuthBetterAuth } from '@mastra/auth-better-auth';
38
+ *
39
+ * // Create your Better Auth instance
40
+ * const auth = betterAuth({
41
+ * database: {
42
+ * provider: 'postgresql',
43
+ * url: process.env.DATABASE_URL!,
44
+ * },
45
+ * emailAndPassword: {
46
+ * enabled: true,
47
+ * },
48
+ * });
49
+ *
50
+ * // Create the Mastra auth provider
51
+ * const mastraAuth = new MastraAuthBetterAuth({
52
+ * auth,
53
+ * });
54
+ *
55
+ * // Use with Mastra
56
+ * const mastra = new Mastra({
57
+ * server: {
58
+ * auth: mastraAuth,
59
+ * },
60
+ * });
61
+ * ```
62
+ *
63
+ * @see https://better-auth.com for Better Auth documentation
64
+ */
65
+ export declare class MastraAuthBetterAuth extends MastraAuthProvider<BetterAuthUser> implements IUserProvider<EEUser>, ICredentialsProvider<EEUser> {
66
+ protected auth: Auth;
67
+ protected signUpEnabledConfig: boolean;
68
+ sessionCookieName: string;
69
+ constructor(options: MastraAuthBetterAuthOptions);
70
+ /**
71
+ * Check if sign-up is enabled.
72
+ * Implements ICredentialsProvider.isSignUpEnabled.
73
+ */
74
+ isSignUpEnabled(): boolean;
75
+ /**
76
+ * Get current user from request.
77
+ * Implements IUserProvider for EE user awareness in Studio.
78
+ *
79
+ * @param request - Incoming HTTP request
80
+ * @returns EE User object or null if not authenticated
81
+ */
82
+ getCurrentUser(request: Request): Promise<EEUser | null>;
83
+ /**
84
+ * Get user by ID.
85
+ * Implements IUserProvider for EE user awareness.
86
+ *
87
+ * Note: Better Auth doesn't expose a direct getUser API.
88
+ * For full functionality, you may need to implement this using
89
+ * direct database access in a subclass.
90
+ *
91
+ * @param userId - User identifier
92
+ * @returns EE User object or null if not found
93
+ */
94
+ getUser(_userId: string): Promise<EEUser | null>;
95
+ /**
96
+ * Get URL to user's profile page.
97
+ * Optional IUserProvider method.
98
+ */
99
+ getUserProfileUrl(user: EEUser): string;
100
+ /**
101
+ * Authenticate a bearer token by verifying the session with Better Auth.
102
+ *
103
+ * This method extracts the session from the request headers using
104
+ * Better Auth's `api.getSession()` endpoint.
105
+ *
106
+ * @param token - The bearer token (session token) to authenticate
107
+ * @param request - The Hono request object containing headers
108
+ * @returns The authenticated user and session, or null if authentication fails
109
+ */
110
+ authenticateToken(token: string, request: HonoRequest): Promise<BetterAuthUser | null>;
111
+ /**
112
+ * Authorize a user for access.
113
+ *
114
+ * By default, any authenticated user with a valid session is authorized.
115
+ * You can override this behavior by providing a custom `authorizeUser` function
116
+ * in the constructor options.
117
+ *
118
+ * @param user - The authenticated user and session
119
+ * @returns True if the user is authorized, false otherwise
120
+ */
121
+ authorizeUser(user: BetterAuthUser): Promise<boolean>;
122
+ /**
123
+ * Sign in with email and password.
124
+ * Implements ICredentialsProvider for EE credentials auth.
125
+ *
126
+ * @param email - User email
127
+ * @param password - User password
128
+ * @param request - Incoming HTTP request
129
+ * @returns Result with user and session cookies
130
+ * @throws Error if credentials are invalid
131
+ */
132
+ signIn(email: string, password: string, request: Request): Promise<CredentialsResult<EEUser>>;
133
+ /**
134
+ * Sign up with email and password.
135
+ * Implements ICredentialsProvider for EE credentials auth.
136
+ *
137
+ * @param email - User email
138
+ * @param password - User password
139
+ * @param name - Optional display name
140
+ * @param request - Incoming HTTP request
141
+ * @returns Result with new user and session cookies
142
+ * @throws Error if sign up fails
143
+ */
144
+ signUp(email: string, password: string, name: string | undefined, request: Request): Promise<CredentialsResult<EEUser>>;
145
+ /**
146
+ * Get the underlying Better Auth instance.
147
+ * Useful for accessing Better Auth APIs directly.
148
+ */
149
+ getAuth(): Auth;
150
+ /**
151
+ * Get headers to clear the session cookies on logout.
152
+ * Partial ISessionProvider implementation for logout support.
153
+ *
154
+ * Clears Better Auth's default session cookies.
155
+ */
156
+ getClearSessionHeaders(): Record<string, string>;
157
+ }
158
+ export {};
159
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAChG,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AACrE,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAEzD,OAAO,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,MAAM,CAAC;AAExC;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,IAAI,CAAC;CACZ;AAmBD,UAAU,2BAA4B,SAAQ,yBAAyB,CAAC,cAAc,CAAC;IACrF;;;OAGG;IACH,IAAI,EAAE,IAAI,CAAC;IAEX;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,qBAAa,oBACX,SAAQ,kBAAkB,CAAC,cAAc,CACzC,YAAW,aAAa,CAAC,MAAM,CAAC,EAAE,oBAAoB,CAAC,MAAM,CAAC;IAE9D,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC;IACrB,SAAS,CAAC,mBAAmB,EAAE,OAAO,CAAC;IAChC,iBAAiB,EAAE,MAAM,CAAC;gBAErB,OAAO,EAAE,2BAA2B;IAoBhD;;;OAGG;IACH,eAAe,IAAI,OAAO;IAS1B;;;;;;OAMG;IACG,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAa9D;;;;;;;;;;OAUG;IACG,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAWtD;;;OAGG;IACH,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAIvC;;;;;;;;;OASG;IACG,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IA0C5F;;;;;;;;;OASG;IACG,aAAa,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC;IAU3D;;;;;;;;;OASG;IACG,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAoCnG;;;;;;;;;;OAUG;IACG,MAAM,CACV,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAqCrC;;;OAGG;IACH,OAAO,IAAI,IAAI;IAIf;;;;;OAKG;IACH,sBAAsB,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;CAUjD"}
package/dist/index.js ADDED
@@ -0,0 +1,245 @@
1
+ import { MastraAuthProvider } from '@mastra/core/server';
2
+
3
+ // src/index.ts
4
+ function mapBetterAuthUserToEEUser(user) {
5
+ return {
6
+ id: user.id,
7
+ email: user.email,
8
+ name: user.name,
9
+ avatarUrl: user.image ?? void 0,
10
+ metadata: {
11
+ emailVerified: user.emailVerified,
12
+ createdAt: user.createdAt,
13
+ updatedAt: user.updatedAt
14
+ }
15
+ };
16
+ }
17
+ var MastraAuthBetterAuth = class extends MastraAuthProvider {
18
+ auth;
19
+ signUpEnabledConfig;
20
+ sessionCookieName;
21
+ constructor(options) {
22
+ super({ name: options?.name ?? "better-auth" });
23
+ if (!options.auth) {
24
+ throw new Error(
25
+ "Better Auth instance is required. Please provide the auth option with your Better Auth instance created via betterAuth({ ... })"
26
+ );
27
+ }
28
+ this.auth = options.auth;
29
+ this.signUpEnabledConfig = options.signUpEnabled ?? true;
30
+ const authWithOptions = this.auth;
31
+ const prefix = authWithOptions.options?.advanced?.cookiePrefix ?? "better-auth";
32
+ this.sessionCookieName = `${prefix}.session_token`;
33
+ this.registerOptions(options);
34
+ }
35
+ /**
36
+ * Check if sign-up is enabled.
37
+ * Implements ICredentialsProvider.isSignUpEnabled.
38
+ */
39
+ isSignUpEnabled() {
40
+ return this.signUpEnabledConfig;
41
+ }
42
+ // ============================================
43
+ // IUserProvider implementation (EE capability)
44
+ // License check happens in buildCapabilities()
45
+ // ============================================
46
+ /**
47
+ * Get current user from request.
48
+ * Implements IUserProvider for EE user awareness in Studio.
49
+ *
50
+ * @param request - Incoming HTTP request
51
+ * @returns EE User object or null if not authenticated
52
+ */
53
+ async getCurrentUser(request) {
54
+ try {
55
+ const result = await this.auth.api.getSession({
56
+ headers: request.headers
57
+ });
58
+ if (!result?.user) return null;
59
+ return mapBetterAuthUserToEEUser(result.user);
60
+ } catch {
61
+ return null;
62
+ }
63
+ }
64
+ /**
65
+ * Get user by ID.
66
+ * Implements IUserProvider for EE user awareness.
67
+ *
68
+ * Note: Better Auth doesn't expose a direct getUser API.
69
+ * For full functionality, you may need to implement this using
70
+ * direct database access in a subclass.
71
+ *
72
+ * @param userId - User identifier
73
+ * @returns EE User object or null if not found
74
+ */
75
+ async getUser(_userId) {
76
+ console.warn(
77
+ "[MastraAuthBetterAuth] getUser() requires direct database access. Override this method in a subclass for full user lookup support."
78
+ );
79
+ return null;
80
+ }
81
+ /**
82
+ * Get URL to user's profile page.
83
+ * Optional IUserProvider method.
84
+ */
85
+ getUserProfileUrl(user) {
86
+ return `/profile/${user.id}`;
87
+ }
88
+ /**
89
+ * Authenticate a bearer token by verifying the session with Better Auth.
90
+ *
91
+ * This method extracts the session from the request headers using
92
+ * Better Auth's `api.getSession()` endpoint.
93
+ *
94
+ * @param token - The bearer token (session token) to authenticate
95
+ * @param request - The Hono request object containing headers
96
+ * @returns The authenticated user and session, or null if authentication fails
97
+ */
98
+ async authenticateToken(token, request) {
99
+ try {
100
+ const headers = new Headers();
101
+ const rawRequest = "raw" in request ? request.raw : request;
102
+ const cookieHeader = rawRequest.headers.get("Cookie");
103
+ if (cookieHeader) {
104
+ headers.set("Cookie", cookieHeader);
105
+ }
106
+ const hasSessionCookie = !!cookieHeader?.split(";").some((pair) => {
107
+ const [key] = pair.trim().split("=");
108
+ return key?.trim() === this.sessionCookieName;
109
+ });
110
+ if (token && !hasSessionCookie) {
111
+ const existingCookies = cookieHeader ? `${cookieHeader}; ` : "";
112
+ headers.set("Cookie", `${existingCookies}${this.sessionCookieName}=${token}`);
113
+ }
114
+ const result = await this.auth.api.getSession({
115
+ headers
116
+ });
117
+ if (!result || !result.session || !result.user) {
118
+ return null;
119
+ }
120
+ return {
121
+ session: result.session,
122
+ user: result.user
123
+ };
124
+ } catch {
125
+ return null;
126
+ }
127
+ }
128
+ /**
129
+ * Authorize a user for access.
130
+ *
131
+ * By default, any authenticated user with a valid session is authorized.
132
+ * You can override this behavior by providing a custom `authorizeUser` function
133
+ * in the constructor options.
134
+ *
135
+ * @param user - The authenticated user and session
136
+ * @returns True if the user is authorized, false otherwise
137
+ */
138
+ async authorizeUser(user) {
139
+ return !!user?.session?.id && !!user?.user?.id;
140
+ }
141
+ // ============================================
142
+ // ICredentialsProvider implementation (EE capability)
143
+ // License check happens in buildCapabilities()
144
+ // ============================================
145
+ /**
146
+ * Sign in with email and password.
147
+ * Implements ICredentialsProvider for EE credentials auth.
148
+ *
149
+ * @param email - User email
150
+ * @param password - User password
151
+ * @param request - Incoming HTTP request
152
+ * @returns Result with user and session cookies
153
+ * @throws Error if credentials are invalid
154
+ */
155
+ async signIn(email, password, request) {
156
+ const headers = request?.headers ?? new Headers();
157
+ const response = await this.auth.api.signInEmail({
158
+ body: { email, password },
159
+ headers,
160
+ asResponse: true
161
+ });
162
+ if (!response.ok) {
163
+ const errorData = await response.json().catch(() => ({}));
164
+ throw new Error(errorData.message || "Invalid email or password");
165
+ }
166
+ const result = await response.json();
167
+ if (!result?.user) {
168
+ throw new Error("Invalid email or password");
169
+ }
170
+ const cookies = [];
171
+ const setCookieHeader = response.headers.get("set-cookie");
172
+ if (setCookieHeader) {
173
+ cookies.push(...setCookieHeader.split(/,(?=\s*\w+=)/));
174
+ }
175
+ return {
176
+ user: mapBetterAuthUserToEEUser(result.user),
177
+ token: result.token ?? void 0,
178
+ cookies
179
+ };
180
+ }
181
+ /**
182
+ * Sign up with email and password.
183
+ * Implements ICredentialsProvider for EE credentials auth.
184
+ *
185
+ * @param email - User email
186
+ * @param password - User password
187
+ * @param name - Optional display name
188
+ * @param request - Incoming HTTP request
189
+ * @returns Result with new user and session cookies
190
+ * @throws Error if sign up fails
191
+ */
192
+ async signUp(email, password, name, request) {
193
+ const displayName = name ?? email.split("@")[0] ?? "User";
194
+ const headers = request?.headers ?? new Headers();
195
+ const response = await this.auth.api.signUpEmail({
196
+ body: { email, password, name: displayName },
197
+ headers,
198
+ asResponse: true
199
+ });
200
+ if (!response.ok) {
201
+ const errorData = await response.json().catch(() => ({}));
202
+ throw new Error(errorData.message || "Failed to create account");
203
+ }
204
+ const result = await response.json();
205
+ if (!result?.user) {
206
+ throw new Error("Failed to create account");
207
+ }
208
+ const cookies = [];
209
+ const setCookieHeader = response.headers.get("set-cookie");
210
+ if (setCookieHeader) {
211
+ cookies.push(...setCookieHeader.split(/,(?=\s*\w+=)/));
212
+ }
213
+ return {
214
+ user: mapBetterAuthUserToEEUser(result.user),
215
+ token: result.token ?? void 0,
216
+ cookies
217
+ };
218
+ }
219
+ /**
220
+ * Get the underlying Better Auth instance.
221
+ * Useful for accessing Better Auth APIs directly.
222
+ */
223
+ getAuth() {
224
+ return this.auth;
225
+ }
226
+ /**
227
+ * Get headers to clear the session cookies on logout.
228
+ * Partial ISessionProvider implementation for logout support.
229
+ *
230
+ * Clears Better Auth's default session cookies.
231
+ */
232
+ getClearSessionHeaders() {
233
+ const cookies = [
234
+ `${this.sessionCookieName}=; Path=/; HttpOnly; SameSite=Lax; Max-Age=0`,
235
+ `${this.sessionCookieName}_sig=; Path=/; HttpOnly; SameSite=Lax; Max-Age=0`
236
+ ];
237
+ return {
238
+ "Set-Cookie": cookies.join(", ")
239
+ };
240
+ }
241
+ };
242
+
243
+ export { MastraAuthBetterAuth };
244
+ //# sourceMappingURL=index.js.map
245
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import type { IUserProvider, ICredentialsProvider, CredentialsResult } from '@mastra/core/auth';\nimport type { EEUser } from '@mastra/core/auth/ee';\nimport type { MastraAuthProviderOptions } from '@mastra/core/server';\nimport { MastraAuthProvider } from '@mastra/core/server';\n\nimport type { Auth, Session, User } from 'better-auth';\nimport type { HonoRequest } from 'hono';\n\n/**\n * User type returned by Better Auth session verification.\n * Used internally for authentication token verification.\n */\nexport interface BetterAuthUser {\n session: Session;\n user: User;\n}\n\n/**\n * Maps Better Auth User to EE User format.\n */\nfunction mapBetterAuthUserToEEUser(user: User): EEUser {\n return {\n id: user.id,\n email: user.email,\n name: user.name,\n avatarUrl: user.image ?? undefined,\n metadata: {\n emailVerified: user.emailVerified,\n createdAt: user.createdAt,\n updatedAt: user.updatedAt,\n },\n };\n}\n\ninterface MastraAuthBetterAuthOptions extends MastraAuthProviderOptions<BetterAuthUser> {\n /**\n * The Better Auth instance to use for authentication.\n * This should be the result of calling `betterAuth({ ... })`.\n */\n auth: Auth;\n\n /**\n * Whether to allow new user registration via sign-up.\n * Set to false to disable public registration.\n * @default true\n */\n signUpEnabled?: boolean;\n}\n\n/**\n * Mastra authentication provider for Better Auth.\n *\n * Better Auth is a self-hosted, open-source authentication framework\n * that gives you full control over your authentication system.\n *\n * @example\n * ```typescript\n * import { betterAuth } from 'better-auth';\n * import { MastraAuthBetterAuth } from '@mastra/auth-better-auth';\n *\n * // Create your Better Auth instance\n * const auth = betterAuth({\n * database: {\n * provider: 'postgresql',\n * url: process.env.DATABASE_URL!,\n * },\n * emailAndPassword: {\n * enabled: true,\n * },\n * });\n *\n * // Create the Mastra auth provider\n * const mastraAuth = new MastraAuthBetterAuth({\n * auth,\n * });\n *\n * // Use with Mastra\n * const mastra = new Mastra({\n * server: {\n * auth: mastraAuth,\n * },\n * });\n * ```\n *\n * @see https://better-auth.com for Better Auth documentation\n */\nexport class MastraAuthBetterAuth\n extends MastraAuthProvider<BetterAuthUser>\n implements IUserProvider<EEUser>, ICredentialsProvider<EEUser>\n{\n protected auth: Auth;\n protected signUpEnabledConfig: boolean;\n public sessionCookieName: string;\n\n constructor(options: MastraAuthBetterAuthOptions) {\n super({ name: options?.name ?? 'better-auth' });\n\n if (!options.auth) {\n throw new Error(\n 'Better Auth instance is required. Please provide the auth option with your Better Auth instance created via betterAuth({ ... })',\n );\n }\n\n this.auth = options.auth;\n this.signUpEnabledConfig = options.signUpEnabled ?? true;\n\n // Derive the session cookie name from Better Auth's cookiePrefix option\n const authWithOptions = this.auth as unknown as { options?: { advanced?: { cookiePrefix?: string } } };\n const prefix = authWithOptions.options?.advanced?.cookiePrefix ?? 'better-auth';\n this.sessionCookieName = `${prefix}.session_token`;\n\n this.registerOptions(options);\n }\n\n /**\n * Check if sign-up is enabled.\n * Implements ICredentialsProvider.isSignUpEnabled.\n */\n isSignUpEnabled(): boolean {\n return this.signUpEnabledConfig;\n }\n\n // ============================================\n // IUserProvider implementation (EE capability)\n // License check happens in buildCapabilities()\n // ============================================\n\n /**\n * Get current user from request.\n * Implements IUserProvider for EE user awareness in Studio.\n *\n * @param request - Incoming HTTP request\n * @returns EE User object or null if not authenticated\n */\n async getCurrentUser(request: Request): Promise<EEUser | null> {\n try {\n const result = await this.auth.api.getSession({\n headers: request.headers,\n });\n\n if (!result?.user) return null;\n return mapBetterAuthUserToEEUser(result.user);\n } catch {\n return null;\n }\n }\n\n /**\n * Get user by ID.\n * Implements IUserProvider for EE user awareness.\n *\n * Note: Better Auth doesn't expose a direct getUser API.\n * For full functionality, you may need to implement this using\n * direct database access in a subclass.\n *\n * @param userId - User identifier\n * @returns EE User object or null if not found\n */\n async getUser(_userId: string): Promise<EEUser | null> {\n // Better Auth doesn't have a direct getUser API\n // Users can override this method with their own implementation\n // that queries the database directly\n console.warn(\n '[MastraAuthBetterAuth] getUser() requires direct database access. ' +\n 'Override this method in a subclass for full user lookup support.',\n );\n return null;\n }\n\n /**\n * Get URL to user's profile page.\n * Optional IUserProvider method.\n */\n getUserProfileUrl(user: EEUser): string {\n return `/profile/${user.id}`;\n }\n\n /**\n * Authenticate a bearer token by verifying the session with Better Auth.\n *\n * This method extracts the session from the request headers using\n * Better Auth's `api.getSession()` endpoint.\n *\n * @param token - The bearer token (session token) to authenticate\n * @param request - The Hono request object containing headers\n * @returns The authenticated user and session, or null if authentication fails\n */\n async authenticateToken(token: string, request: HonoRequest): Promise<BetterAuthUser | null> {\n try {\n // Better Auth's api.getSession() reads session tokens from the Cookie header\n const headers = new Headers();\n\n // The auth middleware may pass a raw Request (c.req.raw) instead of HonoRequest,\n // so unwrap via 'raw' property detection and use the standard Web API.\n const rawRequest: Request = 'raw' in request ? (request as any).raw : (request as unknown as Request);\n\n const cookieHeader = rawRequest.headers.get('Cookie');\n if (cookieHeader) {\n headers.set('Cookie', cookieHeader);\n }\n\n // Convert Bearer token to a session cookie if not already present.\n // better-auth ignores the Authorization header — it only reads from Cookie.\n const hasSessionCookie = !!cookieHeader?.split(';').some(pair => {\n const [key] = pair.trim().split('=');\n return key?.trim() === this.sessionCookieName;\n });\n if (token && !hasSessionCookie) {\n const existingCookies = cookieHeader ? `${cookieHeader}; ` : '';\n headers.set('Cookie', `${existingCookies}${this.sessionCookieName}=${token}`);\n }\n\n const result = await this.auth.api.getSession({\n headers,\n });\n\n if (!result || !result.session || !result.user) {\n return null;\n }\n\n return {\n session: result.session,\n user: result.user,\n };\n } catch {\n return null;\n }\n }\n\n /**\n * Authorize a user for access.\n *\n * By default, any authenticated user with a valid session is authorized.\n * You can override this behavior by providing a custom `authorizeUser` function\n * in the constructor options.\n *\n * @param user - The authenticated user and session\n * @returns True if the user is authorized, false otherwise\n */\n async authorizeUser(user: BetterAuthUser): Promise<boolean> {\n // By default, any authenticated user with a valid session is authorized\n return !!user?.session?.id && !!user?.user?.id;\n }\n\n // ============================================\n // ICredentialsProvider implementation (EE capability)\n // License check happens in buildCapabilities()\n // ============================================\n\n /**\n * Sign in with email and password.\n * Implements ICredentialsProvider for EE credentials auth.\n *\n * @param email - User email\n * @param password - User password\n * @param request - Incoming HTTP request\n * @returns Result with user and session cookies\n * @throws Error if credentials are invalid\n */\n async signIn(email: string, password: string, request: Request): Promise<CredentialsResult<EEUser>> {\n const headers = request?.headers ?? new Headers();\n\n // Use asResponse: true to get the full response with Set-Cookie headers\n const response = await this.auth.api.signInEmail({\n body: { email, password },\n headers,\n asResponse: true,\n });\n\n if (!response.ok) {\n const errorData = (await response.json().catch(() => ({}))) as { message?: string };\n throw new Error(errorData.message || 'Invalid email or password');\n }\n\n const result = (await response.json()) as { user?: User; token?: string | null };\n\n if (!result?.user) {\n throw new Error('Invalid email or password');\n }\n\n // Extract Set-Cookie headers from Better Auth response\n const cookies: string[] = [];\n const setCookieHeader = response.headers.get('set-cookie');\n if (setCookieHeader) {\n // Split multiple cookies (they may be comma-separated or in multiple headers)\n cookies.push(...setCookieHeader.split(/,(?=\\s*\\w+=)/));\n }\n\n return {\n user: mapBetterAuthUserToEEUser(result.user),\n token: result.token ?? undefined,\n cookies,\n };\n }\n\n /**\n * Sign up with email and password.\n * Implements ICredentialsProvider for EE credentials auth.\n *\n * @param email - User email\n * @param password - User password\n * @param name - Optional display name\n * @param request - Incoming HTTP request\n * @returns Result with new user and session cookies\n * @throws Error if sign up fails\n */\n async signUp(\n email: string,\n password: string,\n name: string | undefined,\n request: Request,\n ): Promise<CredentialsResult<EEUser>> {\n const displayName = name ?? email.split('@')[0] ?? 'User';\n const headers = request?.headers ?? new Headers();\n\n // Use asResponse: true to get the full response with Set-Cookie headers\n const response = await this.auth.api.signUpEmail({\n body: { email, password, name: displayName },\n headers,\n asResponse: true,\n });\n\n if (!response.ok) {\n const errorData = (await response.json().catch(() => ({}))) as { message?: string };\n throw new Error(errorData.message || 'Failed to create account');\n }\n\n const result = (await response.json()) as { user?: User; token?: string | null };\n\n if (!result?.user) {\n throw new Error('Failed to create account');\n }\n\n // Extract Set-Cookie headers from Better Auth response\n const cookies: string[] = [];\n const setCookieHeader = response.headers.get('set-cookie');\n if (setCookieHeader) {\n // Split multiple cookies (they may be comma-separated or in multiple headers)\n cookies.push(...setCookieHeader.split(/,(?=\\s*\\w+=)/));\n }\n\n return {\n user: mapBetterAuthUserToEEUser(result.user),\n token: result.token ?? undefined,\n cookies,\n };\n }\n\n /**\n * Get the underlying Better Auth instance.\n * Useful for accessing Better Auth APIs directly.\n */\n getAuth(): Auth {\n return this.auth;\n }\n\n /**\n * Get headers to clear the session cookies on logout.\n * Partial ISessionProvider implementation for logout support.\n *\n * Clears Better Auth's default session cookies.\n */\n getClearSessionHeaders(): Record<string, string> {\n // Clear both the session token and its signature cookie\n const cookies = [\n `${this.sessionCookieName}=; Path=/; HttpOnly; SameSite=Lax; Max-Age=0`,\n `${this.sessionCookieName}_sig=; Path=/; HttpOnly; SameSite=Lax; Max-Age=0`,\n ];\n return {\n 'Set-Cookie': cookies.join(', '),\n };\n }\n}\n"]}
package/package.json ADDED
@@ -0,0 +1,63 @@
1
+ {
2
+ "name": "@mastra/auth-better-auth",
3
+ "version": "0.0.0-agent-chat-ui-20260305212602",
4
+ "description": "Mastra Better Auth integration - self-hosted authentication",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": {
11
+ "types": "./dist/index.d.ts",
12
+ "default": "./dist/index.js"
13
+ },
14
+ "require": {
15
+ "types": "./dist/index.d.ts",
16
+ "default": "./dist/index.cjs"
17
+ }
18
+ },
19
+ "./package.json": "./package.json"
20
+ },
21
+ "license": "Apache-2.0",
22
+ "dependencies": {
23
+ "better-auth": "^1.4.18"
24
+ },
25
+ "peerDependencies": {
26
+ "@mastra/core": "0.0.0-agent-chat-ui-20260305212602"
27
+ },
28
+ "devDependencies": {
29
+ "@types/node": "22.19.7",
30
+ "hono": "^4.11.9",
31
+ "@vitest/coverage-v8": "4.0.18",
32
+ "@vitest/ui": "4.0.18",
33
+ "eslint": "^9.37.0",
34
+ "tsup": "^8.5.1",
35
+ "typescript": "^5.9.3",
36
+ "vitest": "4.0.18",
37
+ "@internal/lint": "0.0.0-agent-chat-ui-20260305212602",
38
+ "@mastra/core": "0.0.0-agent-chat-ui-20260305212602",
39
+ "@internal/types-builder": "0.0.0-agent-chat-ui-20260305212602"
40
+ },
41
+ "files": [
42
+ "dist",
43
+ "CHANGELOG.md"
44
+ ],
45
+ "homepage": "https://mastra.ai",
46
+ "repository": {
47
+ "type": "git",
48
+ "url": "git+https://github.com/mastra-ai/mastra.git",
49
+ "directory": "auth/better-auth"
50
+ },
51
+ "bugs": {
52
+ "url": "https://github.com/mastra-ai/mastra/issues"
53
+ },
54
+ "engines": {
55
+ "node": ">=22.13.0"
56
+ },
57
+ "scripts": {
58
+ "build": "tsup --silent --config tsup.config.ts",
59
+ "build:watch": "tsup --watch --silent --config tsup.config.ts",
60
+ "test": "vitest run",
61
+ "lint": "eslint ."
62
+ }
63
+ }